sed search and replace strings containing /
Don't escape the backslashes; you'll confuse yourself. Use a different symbol after the s
command that doesn't appear in the text (I'm using %
in the example below):
line_old='myparam /path/to/a argB=/path/to/B xo'
line_new='myparam /path/to/c argB=/path/to/D xo'
sed -i "s%$line_old%$line_new%g" /etc/myconfig
Also, enclose the whole string in double quotes; using single quotes means that sed
sees $line
(in the original) instead of the expanded value. Inside single quotes, there is no expansion and there are no metacharacters. If your text can contain almost any plain text character, use a control character (e.g. control-A or control-G) as the delimiter.
Note that the use of -i
here mirrors what is in the question, but that assumes the use of GNU sed
. BSD sed
(found on Mac OS X too) requires a suffix. You can use sed -i '' …
to replace in situ; that does not work with GNU sed
. To be portable between the two, use -i.bak
; that will work with both — but gives you a backup file that you'll probably want to delete. Other Unix platforms (e.g. AIX, HP-UX, Solaris) may have variants of sed
that do not support -i
at all. It is not required by the POSIX specification for sed
.
Linux/Unix Replacing a pattern in a string and saving to a new file with sed
You can try this sed
command
sed 's/,\(.*china\)/,Tomas_proxy.lt\/\1/' FileName
or
sed 's/,\(.*china\)/,Tomas_proxy.lt\/\1/' FileName > NewFile
or
sed -i.bak 's/,\(.*china\)/,Tomas_proxy.lt\/\1/' FileName
how to use sed to replace a string in a file with a shell variable
It seems to be that you're trying a combination of piping to sed and using a file. The following will work perfectly fine,
sed -i -e "s/{VERSION}/${VERSION}/" -e "s/{DISTRO}/${DISTRO}/" ${OUT_CAT}
You don't need to escape the $
, and you don't pipe into sed
since you're using -i
to modify the file in-place. You also need to use -e
for each expression when their are more than one.
EDIT: Here is the bit in the sed manual pages that gives the indication of the issue with -e
option (emphasis mine),
If no -e, --expression, -f, or --file option is given, then the first
non-option argument is taken as the sed script to interpret. All
remaining arguments are names of input files; if no input files are
specified, then the standard input is read.
Sed command to change a string at only desired place
Is there any way to replace the string using a WHERE clause so I can replace the string only where I want?
sed
does not have SQL-style WHERE
clauses, but commands can have "addresses" that define subsets of input lines to operate upon. These can take several forms. Regular expressions are perhaps the most common, but there are also line numbers, and a couple of special forms. You can also have inclusive ranges built from simple addresses. An address range would be a reasonably good way to address the problem you present.
For example,
sed -i '/^\s*-\s*stage:\s*Moto_Dev/,/^\s*-/ s/dependsOn: Build/dependsOn: Test/' input
Explanation:
The
-i
command-line flag tellssed
to work "in-place", which really means that it will replace the original file with one containingsed
's output.The
/^\s*-\s*stage:\s*Moto_Dev/,/^\s*-/
is a range address, consisting of a regex for the range start (/^\s*-\s*stage:\s*MotoDev/
) and one for the range end (/^\s*-/
)./^\s*-\s*stage:\s*Moto_Dev/
matches the beginning of the section in which you want the change to be made, with some flexibility around the exact amount of whitespace at certain positions. For brevity and clarity, it uses\s
to represent a single space or tab character. That is a GNU extension, but if you cannot depend on GNUsed
then there are other ways to express the same thing./^\s*-/
matches the beginning of the next section, as you have presented the input. It could be made more specific if it were necessary to be more selective.
The range includes its endpoints, but that does not appear to be a problem for the task at hand.
There is only one such range in the input presented, and that range contains the line you want to modify. The specified substitution,
s/dependsOn: Build/dependsOn: Test/
, is performed on each line in the range, but only the one contains a match to be replaced. All others in the range will be unaffected.No commands at all are specified for lines outside the range, so they too will be unaffected.
You also asked,
I stored the desired piece of code in a variable. Can I use that
variable in ased
command? For example,sed -i "s/condition: succeeded('Fair_PreProd')/condition: succeeded('Fair_UAT')/g" $folder_path/$file_name
sed
does not expand shell-style parameter references, but you don't need it to do. The variable references in that command are expanded by the shell itself, before it executes the resulting command, so
- yes, you may use them, and
- it's not a question of using shell variables with
sed
in particular.
How to replace strings of a text file based on two list using sed
With GNU sed you can match beginning and ending of a word with \<
\>
. You may first generate a sed script from your input then pass it to sed. There have to be no special characters in input.
script=$(
paste OLD_SM.list NEW_SM.list |
sed 's/\(.*\)\t\(.*\)/s~\\<\1\\>~\2~g/'
)
sed -i "/^#CHROM/{ $script }" file.
The s/[[:space:]]${OLD_SM}$
- the $
matches end of line, so it's never going to work. You may do s/\(^\|[[:space:]]\)$OLD_SM\([[:space:]]\|$\)/\1$NEW_SM\2/
- match beginning of a line or space, then the word, then space or ending of line, and then substitute for backreference. Topics to research: regex and backreferences in sed.
How to find and replace string in a file WITHOUT sed
You can use awk
for find and replace as well. Here's a resource with more detail..
For example, your makefile command could be replaced with:
omz-theme:
awk -v var="ZSH_THEME=$(echo THEME)" '{sub(/^ZSH_THEME=.*$/, var); print}' $(HOME)/.zshrc
You could use this to overwrite the existing $(HOME)/.zshrc
file using redirection:
omz-theme:
awk -v var="ZSH_THEME=$(echo THEME)" '{sub(/^ZSH_THEME=.*$/, var); print}' $(HOME)/.zshrc > $(HOME)/.zshrc
Alternately, you could check the OS using OSTYPE
and then use the correct sed
syntax for BSD and GNU:
omz-theme:
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
sed -i 's/ZSH_THEME=".*"/ZSH_THEME="$(THEME)"/g' $(HOME)/.zshrc
else
sed -i '' 's/ZSH_THEME=".*"/ZSH_THEME="$(THEME)"/g' $(HOME)/.zshrc
fi
(note: I didn't test the above, but you get the idea)
Related Topics
Reliably Kill Sleep Process After Usr1 Signal
Find a Line in a File and Add Something to The End of The Line in Bash
How to Start a Nodejs Process on a Remote Server
Docker Installation on Linux Mint 19.2 Doesn't Work
How to Print $ in Shell Script
How to Disable Tcp Slow Start in Linux
Git Error: Gpg Failed to Sign The Data on Linux
Joining Line Breaks in Fasta File with Condition in Sed/Awk/Perl One-Liner
How Linux Scheduler Schedules Processes on Multi-Core Processors
Sending Command to Process Using /Proc
X86 Assembly, Little Endianness Not Being Followed(Or Is It) (Linux)
Is There an Os Command I Can Run to Determine If Running Inside a Xen Based Virtual Machine
Simulate Effect of Select() and Poll() in Kernel Socket Programming