6

I have more than 200 files in one folder on Ubuntu 22.04. I would like to search these for a specific text. If the text is found, it should be replaced by another text. How can I achieve this?

terdon
  • 100,812
D-T
  • 383
  • 1
    It rather depends on the two texts - in particular, whether they are multi-line and whether they are strictly alphanumeric or may contain characters that are special in typical text processing tools. Please [edit] your question to include a minimal representative sample. – steeldriver Nov 29 '23 at 01:11

5 Answers5

15

The basic version is:

sed --in-place 's/foo/bar/g' *

This will search for foo and change it into bar globally. The --in-place flag changes the actual file, so use it carefully. If you add a suffix (--in-place=bak) a backup file with extension "bak" is made.

In case of special characters (and there are many) those need to be escaped. I can not explain this better than Gilles on SO: https://unix.stackexchange.com/a/33005/10017


There is also a tool named rpl (replace strings in files) to make it easier (install it with: sudo apt install rpl), with which you can do:

rpl --dry-run 'foo' 'bar' '*/*.*'

The above command will only simulate (dry run) the operation, thus it will show what changes will happen to your files, but it will not apply those changes. If you are satisfied with what you get, run the command without the --dry-run flag:

rpl 'foo' 'bar' '*/*.*'
Rinzwind
  • 299,756
4

Try this:

grep -rl 'your_old_text' /path/to/folder | xargs sed -i 's/your_old_text/your_new_text/g'  
muru
  • 197,895
  • 55
  • 485
  • 740
D-T
  • 383
4

With perl ... It has a text search and replacement syntax s/SEARCH/REPLACEMENT/ (where SEARCH is processed as a regular expression and REPLACEMENT as "mostly" a string) that supports global search and replace, it has an -inplace file editing command-line option that can save a backup of the file if used e.g. like -i.bak where .bak will be used as an extension for the backed up file/s and it can process multiple files in a single run like so:

perl -i.bak -pe 's/SEARCH/REPLACEMENT/g' folder/*

Demonstration:
$ mkdir folder
$
$
$ for i in {1..3}
  do 
    printf '%s\n' "Line1 in File${i} some SEARCH text and another SEARCH text." "Line2 in File${i} some SEARCH text and another SEARCH text." > folder/file"$i"
    done
$
$
$ head folder/*
==> folder/file1 <==
Line1 in File1 some SEARCH text and another SEARCH text.
Line2 in File1 some SEARCH text and another SEARCH text.

==> folder/file2 <== Line1 in File2 some SEARCH text and another SEARCH text. Line2 in File2 some SEARCH text and another SEARCH text.

==> folder/file3 <== Line1 in File3 some SEARCH text and another SEARCH text. Line2 in File3 some SEARCH text and another SEARCH text. $ $ $ perl -i.bak -pe 's/SEARCH/REPLACEMENT/g' folder/* $ $ $ head folder/* ==> folder/file1 <== Line1 in File1 some REPLACEMENT text and another REPLACEMENT text. Line2 in File1 some REPLACEMENT text and another REPLACEMENT text.

==> folder/file1.bak <== Line1 in File1 some SEARCH text and another SEARCH text. Line2 in File1 some SEARCH text and another SEARCH text.

==> folder/file2 <== Line1 in File2 some REPLACEMENT text and another REPLACEMENT text. Line2 in File2 some REPLACEMENT text and another REPLACEMENT text.

==> folder/file2.bak <== Line1 in File2 some SEARCH text and another SEARCH text. Line2 in File2 some SEARCH text and another SEARCH text.

==> folder/file3 <== Line1 in File3 some REPLACEMENT text and another REPLACEMENT text. Line2 in File3 some REPLACEMENT text and another REPLACEMENT text.

==> folder/file3.bak <== Line1 in File3 some SEARCH text and another SEARCH text. Line2 in File3 some SEARCH text and another SEARCH text.

Raffa
  • 32,237
1

Since folks insist on using a stream editor when a text editor will do, here’s a way using the standard editor:

find dir -type f -exec sh -c 'printf %s\\n g/re/s//repl/g wq | ed -s "$1"' sh {} \;
  • Use find to find files and execute a command.
  • Use ed to perform the substitution and save. Normally one would write %s/re/repl/g to change all occurrences, but ed’s s errors when re can’t be found (and unlike Vim, has no flag to suppress the error). The use of g does mask the error, however.
  • +1 for the link. I'm guilty as well of using sed --in-place for almost any file I need to edit using the command line. I'll try to keep in mind what is said in the link for my future edits. – BeastOfCaerbannog Nov 30 '23 at 14:27
0

if you want to go the GUI way, install an IDE that features a 'replace in all files' functionality.

Jetbrains' IntelliJ and Rider are the ones I know.

Others also should since replacing text in all files of a project is a regular refactoring task.

The advantage of IDEs is that you can manually skip replacements.

stonux
  • 1