- How to use sed to find and replace text in files in Linux / Unix shell
- Find and replace text within a file using sed command
- Syntax: sed find and replace text
- Examples that use sed to find and replace
- sed command problems
- How to use sed to match word and perform find and replace
- Recap and conclusion – Using sed to find and replace text in given files
- Replace one substring for another string in shell script
- 10 Answers 10
- How to replace a string in multiple files in linux command line
- 27 Answers 27
- repren
How to use sed to find and replace text in files in Linux / Unix shell
Find and replace text within a file using sed command
The procedure to change the text in files under Linux/Unix using sed:
- Use Stream EDitor (sed) as follows:
- sed -i ‘s/old-text/new-text/g’ input.txt
- The s is the substitute command of sed for find and replace
- It tells sed to find all occurrences of ‘old-text’ and replace with ‘new-text’ in a file named input.txt
- Verify that file has been updated:
- more input.txt
Let us see syntax and usage in details.
Tutorial details | |
---|---|
Difficulty level | Easy |
Root privileges | No |
Requirements | sed utility on Linux, macOS or Unix-like OS |
Est. reading time | 4 minutes |
Syntax: sed find and replace text
The syntax is:
sed ‘s/word1/word2/g’ input.file
## *bsd/macos sed syntax#
sed ‘s/word1/word2/g’ input.file > output.file
sed -i ‘s/word1/word2/g’ input.file
sed -i -e ‘s/word1/word2/g’ -e ‘s/xx/yy/g’ input.file
## use + separator instead of / ##
sed -i ‘s+regex+new-text+g’ file.txt
The above replace all occurrences of characters in word1 in the pattern space with the corresponding characters from word2.
Examples that use sed to find and replace
Let us create a text file called hello.txt as follows:
$ cat hello.txt
The is a test file created by nixCrft for demo purpose.
foo is good.
Foo is nice.
I love FOO.
I am going to use s/ for substitute the found expression foo with bar as follows:
sed ‘s/foo/bar/g’ hello.txt
Sample outputs:
- No ads and tracking
- In-depth guides for developers and sysadmins at Opensourceflare✨
- Join my Patreon to support independent content creators and start reading latest guides:
- How to set up Redis sentinel cluster on Ubuntu or Debian Linux
- How To Set Up SSH Keys With YubiKey as two-factor authentication (U2F/FIDO2)
- How to set up Mariadb Galera cluster on Ubuntu or Debian Linux
- A podman tutorial for beginners – part I (run Linux containers without Docker and in daemonless mode)
- How to protect Linux against rogue USB devices using USBGuard
Join Patreon ➔
Please note that the BSD implementation of sed (FreeBSD/MacOS and co) does NOT support case-insensitive matching. You need to install gnu sed. Run the following command on Apple Mac OS:
$ brew install gnu-sed
######################################
### now use gsed command as follows ##
######################################
$ gsed -i ‘s/foo/bar/g I ‘ hello.txt
$ cat hello.txt
sed command problems
Consider the following text file:
$ cat input.txt
http:// is outdate.
Consider using https:// for all your needs.
Find word ‘http://’ and replace with ‘https://www.cyberciti.biz’:
sed ‘s/ http:// / https://www.cyberciti.biz /g’ input.txt
You will get an error that read as follows:
Our syntax is correct but the / delimiter character is also part of word1 and word2 in above example. Sed command allows you to change the delimiter / to something else. So I am going to use +:
sed ‘s+ http:// + https://www.cyberciti.biz +g’ input.txt
Sample outputs:
How to use sed to match word and perform find and replace
In this example only find word ‘love’ and replace it with ‘sick’ if line content a specific string such as FOO:
sed -i -e ‘/FOO/s/love/sick/’ input.txt
Use cat command to verify new changes:
cat input.txt
Recap and conclusion – Using sed to find and replace text in given files
The general syntax is as follows:
## find word1 and replace with word2 using sed ##
sed -i ‘s/word1/word2/g’ input
## you can change the delimiter to keep syntax simple ##
sed -i ‘s+word1+word2+g’ input
sed -i ‘s_word1_word2_g’ input
## you can add I option to GNU sed to case insensitive search ##
sed -i ‘s/word1/word2/gI’ input
sed -i ‘s_word1_word2_gI’ input
See BSD(used on macOS too) sed or GNU sed man page by typing the following command:
man sed
🐧 Get the latest tutorials on Linux, Open Source & DevOps via
Источник
Replace one substring for another string in shell script
I have «I love Suzi and Marry» and I want to change «Suzi» to «Sara».
The result must be like this:
10 Answers 10
To replace the first occurrence of a pattern with a given string, use $<parameter/pattern/string> :
To replace all occurrences, use $<parameter//pattern/string> :
Note that this feature is not specified by POSIX — it’s a Bash extension — so not all Unix shells implement it. For the relevant POSIX documentation, see The Open Group Technical Standard Base Specifications, Issue 7, the Shell & Utilities volume, §2.6.2 «Parameter Expansion».
This can be done entirely with bash string manipulation:
That will replace only the first occurrence; to replace them all, double the first slash:
For Dash all previous posts aren’t working
The POSIX sh compatible solution is:
This will replace the first occurrence on each line of input. Add a /g flag to replace all occurrences:
It’s better to use bash than sed if strings have RegExp characters.
It’s portable to Windows and works with at least as old as Bash 3.1.
To show you don’t need to worry much about escaping let’s turn this:
But only if /home/name is in the beginning. We don’t need sed !
Given that bash gives us magic variables $PWD and $HOME , we can:
EDIT: Thanks for Mark Haferkamp in the comments for the note on quoting/escaping
Note how the variable $HOME contains slashes but this didn’t break anything.
to keep Bash from expanding it into $HOME. Also, what does the # in your command do?
«: notice how I quoted stuff. Remember to always quote stuff! And this doesn’t just work for magic variables: any variable is capable of substitutions, getting string length, and more, within bash. Congrats on trying to your $PS1 fast: you may also be interested in $PROMPT_COMMAND if you are more comfortable in another programming language and want to code a compiled prompt.
>» doesn’t replace my $HOME with
‘ works. Any of these work on Bash 4.2.53 on another distro. Can you please update your post to quote or escape the
for better compatibility? What I meant by my «magic variables» question was: Can I use Bash’s variable substitution on, e.g., the output of uname without saving it as a variable first? As for my personal $PROMPT_COMMAND , it’s complicated.
If tomorrow you decide you don’t love Marry either she can be replaced as well:
There must be 50 ways to leave your lover.
- «s» means «substitute»
- «g» means «global, all matching occurrences»
Since I can’t add a comment. @ruaka To make the example more readable write it like this
I know this is old but since no one mentioned about using awk:
Pure POSIX shell method, which unlike Roman Kazanovskyi‘s sed -based answer needs no external tools, just the shell’s own native parameter expansions. Note that long file names are minimized so the code fits better on one line:
Remove Smallest Suffix Pattern. «$
But if t=Zelda , then «$
This is used to test if $t is in $f with [ «$
If the test returns true, construct the desired string using Remove Smallest Suffix Pattern $
Источник
How to replace a string in multiple files in linux command line
I need to replace a string in a lot of files in a folder, with only ssh access to the server. How can I do this?
27 Answers 27
Occurrences of «foo» will be replaced with «bar».
On BSD systems like macOS, you need to provide a backup extension like -i ‘.bak’ or else «risk corruption or partial content» per the manpage.
Similar to Kaspar’s answer but with the g flag to replace all the occurrences on a line.
For global case insensitive:
@kev’s answer is good, but only affects files in the immediate directory.The example below uses grep to recursively find files. It works for me everytime.
grep -r: —recursive, recursively read all files under each directory.
grep -l: —print-with-matches, prints the name of each file that has a match, instead of printing matching lines.
grep -i: —ignore-case.
xargs: transform the STDIN to arguments, follow this answer.
xargs -i@
, the @ sign is a placeholder which could replaced by any string.
sed -i: edit files in place, without backups.
sed s/regexp/replacement/: substitute string matching regexp with replacement.
sed s/regexp/replacement/g: global, make the substitution for each match instead of only the first match.
There are a few standard answers to this already listed. Generally, you can use find to recursively list the files and then do the operations with sed or perl.
For most quick uses, you may find the command rpl is much easier to remember.
Replace foo with bar on all .txt files:
Simulate replacing the regex foo.* with bar in all .txt files recursively:
You’ll probably need to install it ( apt-get install rpl or similar).
repren
However, for tougher jobs that involve regular expressions and back substitution, or file renames as well as search-and-replace, the most general and powerful tool I’m aware of is repren, a small Python script I wrote a while back for some thornier renaming and refactoring tasks. The reasons you might prefer it are:
- Support renaming of files as well as search-and-replace on file contents.
- See changes before you commit to performing the search and replace.
- Support regular expressions with back substitution, whole words, case insensitive, and case preserving (replace foo -> bar, Foo -> Bar, FOO -> BAR) modes.
- Works with multiple replacements, including swaps (foo -> bar and bar -> foo) or sets of non-unique replacements (foo -> bar, f -> x).
To use it, pip install repren . Check the README for examples.
This worked for me:
Howerver, this did not: sed -i ‘s/string1/string2/g’ * . Maybe «foo» was not meant to be string1 and «bar» not string2.
To replace a string in multiple files you can use:
To replace a path within files (avoiding escape characters) you may use the following command:
The @ sign means that all of the special characters should be ignored in a following string.
Given you want to search for the string search and replace it with replace across multiple files, this is my battle-tested, one-line formula:
Quick grep explanation:
- -R — recursive search
- -i — case-insensitive
- -I — skip binary files (you want text, right?)
- -l — print a simple list as output. Needed for the other commands
The grep output is then piped to sed (through xargs) which is used to actually replace text. The -i flag will alter the file directly. Remove it for a kind of «dry run» mode.
In case your string has a forward slash(/) in it, you could change the delimiter to ‘+’.
This command would run recursively in the current directory.
The first line occurrences of «foo» will be replaced with «bar». And you can using the second line to check.
If you have list of files you can use
If you have all files you can use
If you have list of files with extension, you can use
«You could also use find and sed, but I find that this little line of perl works nicely.
- -e means execute the following line of code.
- -i means edit in-place
- -w write warnings
- -p loop
My best results come from using perl and grep (to ensure that file have the search expression )
On a MacBook Pro, I used the following (inspired by https://stackoverflow.com/a/19457213/6169225):
-i » will ensure you are taking no backups.
I did concoct my own solution before I found this question (and answers). I searched for different combinations of «replace» «several» and «xml,» because that was my application, but did not find this particular one.
My problem: I had spring xml files with data for test cases, containing complex objects. A refactor on the java source code changed a lot of classes and did not apply to the xml data files. In order to save the test cases data, I needed to change all the class names in all the xml files, distributed across several directories. All while saving backup copies of the original xml files (although this was not a must, since version control would save me here).
I was looking for some combination of find + sed , because it worked for me in other situations, but not with several replacements at once.
Then I found ask ubuntu response and it helped me build my command line:
And it worked perfectly (well, my case had six different replacements). But please note that it will touch all *.xml files under current directory. Because of that, and if you are accountable to a version control system, you might want to filter first and only pass on to sed those actually having the strings you want; like:
Источник