108

I want to know how I can find and replace a specific text in multiple files like in Notepad++ in the linked tutorial.

e.g.: http://cybernetnews.com/find-replace-multiple-files/

Benoit
  • 7,567
  • 1
  • 25
  • 34
Faruk Uzun
  • 1,280
  • It will not have the graphical interface but I would urge you to examine sed (man sed). It is the stream editor that has been in existence from the start of UNIX. – apolinsky Nov 30 '11 at 14:08

10 Answers10

170

Here I use sed to replace every occurrence of the word "cybernetnews" with "cybernet" in every file with the extension, c, in the directory, /home/user/directory/.

find /home/user/directory -name \*.c -exec sed -i "s/cybernetnews/cybernet/g" {} \;

A more generic variation where you search recursively from the directory of execution and operate on only regular, readable, writeable files:

find ./ -type f -readable -writable -exec sed -i "s/cybernetnews/cybernet/g" {} \;
gregtzar
  • 123
  • 2
    Voted for this because it is such an efficient method – Sabacon Nov 30 '11 at 16:01
  • 4
    Voted up because sed is the best choice IMO, but answer would be more useful if you explained the components of the answer (personally, I'm not familiar with and curious about the {} ;) – Stop Slandering Monica Cellio Nov 30 '11 at 18:50
  • 5
    @sequoiamcdowell Woo! I missed this! Sorry. The braces mean basically "for each match" and the escaped semi-colon (;) is to prevent double parsing. We don't want the bourne-compatible shell and sed trying to parse the command, just sed. –  Jul 03 '12 at 22:34
  • @Christopher how does it work if the word contains spaces like cyber net news? How can i convert this to cyber net? – Khurshid Alam Sep 21 '12 at 18:56
  • 1
    @KhurshidAlam Use the character class with the -e switch: sed -i -e "s/cyber\snet\snews/cyber net/g" –  Sep 22 '12 at 13:28
  • What does the {} \\ mean near the end of the command? – Qian Chen Apr 20 '16 at 08:49
  • If replacing a path, use another separator, like +: "s+/path/to/file+/other/path/to-file+g" – SaTa Feb 01 '21 at 01:50
  • I could not get find to work no matter what I did, but the following worked (find and delete class="Western"), also in sub-directories recursively: sed -i 's/class="western"//g' $(grep -rEl 'class="western"' ./) – Henrik R. Sep 22 '22 at 14:23
  • The only disadvantage with 'grep' was that it also did the find and replace on a non-html file... – Henrik R. Sep 22 '22 at 14:40
32

The stream editor,sed, is a powerful utility for this kind of work and is my first choice, however, if you want to do this from an ordinary text editor using an Ubuntu based native application, I would suggest you take a look at Jedit, It is available in the repositories and can be installed by typing in your console:

sudo apt-get install jedit

Start jedit, click the search menu item, in the menu list, click the Search in Directory item, you will be presented with the dialog below:

Jedit Search In Folder Dialog

This is similar to that of Notepad++ and does the same thing, I believe this is what you want.

Sabacon
  • 40,058
  • 1
    This was perfect for when I was searching for an entire line of code, and was hesitant to escape every single regex-special character if I had done the same thing with sed. – IQAndreas Sep 07 '13 at 19:47
  • you can replace code blocks (like html, javascript, etc) in seconds. – lepe Mar 25 '14 at 09:09
  • 1
    This doesn't work on a large number of files, after a couple of hours it hadn't made one replacement, whereas geany took a few minutes to find all the occurrences. This may not be an efficient search and replace but it warmed the room up nicely. – Mark Aroni Mar 29 '18 at 08:26
  • Netbeans also supports find and replace in files. – Faiyaz Alam Dec 18 '20 at 17:06
20

Another GUI option is regexxer: regexxer screenshot

int_ua
  • 8,574
  • Works perfectly (if you are already familiar with Regex), thank you. – Ernest Feb 03 '14 at 12:10
  • 1
    Even, If you don't know regex, you can use this tool as a simple string search and replace tool and it will do the job for you, no need for regex or anything. – Mohd Abdul Mujib Nov 28 '18 at 17:17
13
perl -pi -e 's/oldtext/newtext/g' *

replaces any occurence of oldtext by newtext in all files in the current folder. However you will have to escape all perl special characters within oldtext and newtext using the backslash.

Michael K
  • 13,888
10

Check with Geany, it is perfect NPP replacement for Linux. You can do exactly that plus you can use regex.

Jorge Castro
  • 71,754
  • I love Geany! It's my favourite editor and is powerful enough. – Stefano Dec 07 '11 at 10:35
  • 1
    As far as I can tell, Geany 1.23.1 (packaged with Ubuntu 13.10) allows searching multiple files using regex, but not replacing in them. – Drew Noakes Dec 11 '13 at 23:35
  • You can search and replace in Geany multiple files if you open them all and then using the "in session" button in the Search/Replace dialog. – MV. May 03 '16 at 22:58
  • 1
    How do you open 5000 files listed in the messages tab? – Mark Aroni Mar 28 '18 at 14:41
  • Frankly how reta**ed/lazy do devs have to be, to implement a bulk search but no replace like wow!! almost all of the applications suggested here fall just short of the finish line, be it searchmonkey (no replace) geany (again no bulk replace) then we have jedit which just hangs when lots of files are thrown at it (in effecient) :( I'm not a desktop developer otherwise you'd have yourself a tool by now >:( This is frustrating, I just need something like text crawler in windows. – Mohd Abdul Mujib Nov 28 '18 at 16:57
  • 1
    Ok, The regexxer was pretty much what I had been asking for, I had just skipped it earlier due to its name having regex and I just tend to avoid anything to do with regex. But I was wrong, adn that tool has exactly what is required for search and replace. – Mohd Abdul Mujib Nov 28 '18 at 17:15
7

A very simple solution: replace in all *.txt files in folder string_1 with string_2:

sed -i 's/string_1/string_2/g' *.txt
Jens Erat
  • 5,051
  • 7
  • 31
  • 37
  • Great answer! Just some addition. If you want to replace a string in any file of the current directory recursively then try this: sed -i 's/string_1/string_2/g' $(grep -rEl 'string_1' ./) – drugan May 12 '18 at 10:08
  • work like charm! – Sadegh PM Apr 20 '21 at 08:19
3

You can use this script, copy code and make a file find_and_replace_in_files.sh.

I have modified it a little; please tell me your opinion.

# *****************************************************************************************
# find_and_replace_in_files.sh
# This script does a recursive, case sensitive directory search and replace of files
# To make a case insensitive search replace, use the -i switch in the grep call
# uses a startdirectory parameter so that you can run it outside of specified directory - else this script will modify itself!
# *****************************************************************************************

!/bin/bash
# **************** Change Variables Here ************
startdirectory="/your/start/directory"
searchterm="test"
replaceterm="test=ok!"
# **********************************************************

echo "***************************************************"
echo "* Search and Replace in Files Version 01-Aug-2012 *"
echo "***************************************************"

i=0; 

  for file in $(grep -l -R $searchterm $startdirectory)
    do
      cp $file $file.bak
      sed -e "s/$searchterm/$replaceterm/ig" $file > tempfile.tmp
      mv tempfile.tmp $file

    let i++;

      echo "Modified: " $file
    done

echo " *** All Done! *** Modified files:" $i
Eliah Kagan
  • 117,780
3
find . -name "*.txt" |xargs sed -i "s/searched_Text/replacement_Text/g"

works for me on fedora

muru
  • 197,895
  • 55
  • 485
  • 740
  • You could add a line explaining how this improves over http://askubuntu.com/a/84013/158442 – muru Sep 19 '14 at 00:30
  • @muru It runs much fewer sed instances! So it is much faster in terms of CPU time. Because the file access time would be limiting, I think it's not much faster in clock time, but gives lower system load. Note xargs will put lots, like hundereds, of filenames on the commandline of a single sed command - filling the available buffer size based on the length of the paths. – Volker Siegel Sep 19 '14 at 01:07
  • Hmm... if this gets closed, I could replace it with one clearly explaining why it's better than the upvoted one. – Volker Siegel Sep 19 '14 at 01:08
  • @VolkerSiegel that can be achieved with + instead of \; in find, right? – muru Sep 19 '14 at 01:21
  • 1
    @muru Possibly... My "rigth tool for the job"-instinct clearly prefers xargs, but you're right; from man find: -exec command {} +: ...The command line is built in much the same way that xargs.... Makes me think of command lines of git filter-branch... ;) – Volker Siegel Sep 19 '14 at 01:26
3

I wrote a little script for just this thing. If you only need the basics and are not familiar with sed etc, take a look here: http://www.csrdu.org/nauman/2010/12/30/bash-script-to-find-and-replace-in-a-set-of-files/

The script is the following:

for f in submit_*;
  do sed "s/old_db_name/new_db_name/" < $f > a_$f ;
  mv a_$f $f ;
done
recluze
  • 1,047
2

Another program is Searchmonkey.

SearchMonkey is a light-weight Gtk application that aims to replace the cumbersome find/grep with a slick user interface that quickly provides a mark-up showing locations and quantity of text matches. The goal is to provide a simple to use and accessible search tool for end-users, and software developers alike.

Drew Noakes
  • 5,708
vrcmr
  • 6,307