find matching text and replace next line
This might work for you (GNU sed):
sed '/<key>ConnectionString<\/key>/!b;n;c<string>changed_value</string>' file
!b
negates the previous address (regexp) and breaks out of any processing, ending the sed commands, n
prints the current line and then reads the next into the pattern space, c
changes the current line to the string following the command.
Find a matching text and replace next two lines in unix
With GNU sed:
sed '/bbb/,+2{ /bbb/b; s/.*/zzz/ }' file
With awk:
awk '/bbb/{print; getline; print "zzz"; getline; print "zzz"; next}1' file
find matching text and replace next line in yml
sed is best for s/old/new, that is all. For anything else just use awk for clarity, portability, robustness, etc. Look:
$ awk -v rec='applicationConnectors' -v tag='port' -v val='14081' '
/^ [^ ]/{name=$1} name==(rec":") && $1==(tag":"){sub(/[^ ]+$/,""); $0=$0 val}
1' file
applicationConnectors:
- type: http
port: 14081
bindHost: 15.213.48.154
headerCacheSize: 512 bytes
outputBufferSize: 32KiB
maxRequestHeaderSize: 8KiB
maxResponseHeaderSize: 8KiB
inputBufferSize: 8KiB
idleTimeout: 30 seconds
minBufferPoolSize: 64 bytes
bufferPoolIncrement: 1KiB
maxBufferPoolSize: 64KiB
acceptorThreads: 1
selectorThreads: 2
acceptQueueSize: 1024
reuseAddress: true
useServerHeader: false
useDateHeader: true
useForwardedHeaders: true
adminConnectors:
- type: http
port: 14180
Want to change acceptQueueSize:
to 17
instead? It's the same script with just different variable values:
$ awk -v rec='applicationConnectors' -v tag='acceptQueueSize' -v val='17' '
/^ [^ ]/{name=$1} name==(rec":") && $1==(tag":"){sub(/[^ ]+$/,""); $0=$0 val}
1' file
applicationConnectors:
- type: http
port: 14080
bindHost: 15.213.48.154
headerCacheSize: 512 bytes
outputBufferSize: 32KiB
maxRequestHeaderSize: 8KiB
maxResponseHeaderSize: 8KiB
inputBufferSize: 8KiB
idleTimeout: 30 seconds
minBufferPoolSize: 64 bytes
bufferPoolIncrement: 1KiB
maxBufferPoolSize: 64KiB
acceptorThreads: 1
selectorThreads: 2
acceptQueueSize: 17
reuseAddress: true
useServerHeader: false
useDateHeader: true
useForwardedHeaders: true
adminConnectors:
- type: http
port: 14180
Only try that with your currently accepted sed
solution if you enjoy counting n
s :-). Note also that this will work no matter what order the lines appear within each record since it keys off the name port
rather than assuming that will appear some specific number of lines after applicationConnectors:
. Finally, this will work even if the strings you're searching for or replacing with contain RE metachars (e.g. .
), backreference chars (e.g. \1
or &
), or sed delimiters (e.g. /
).
Bash: Find matching text and replace next line
Your NEW_FILE
is probably a bash-variable and therefore not a variable in awk. So, either let bash do the expansion:
awk '/working/ { print; print "'$NEW_FILE'"; next}1' test1.txt
or pass/set the variable from the command line:
awk -v NEW_FILE="$NEW_FILE" '/working/ { print; print NEW_FILE; next}1' test1.txt
How to replace 2 consecutive lines after Match with Sed
gnu and some other sed versions allow you to grab a range using relative number so you can simply use:
sed -E '/^#ABC$/,+2 s/(Size=)bar/\1foo/' file
#ABC
oneSize=foo
twoSize=foo
threeSize=foo
Command details:
/^#ABC$/,+2
Match range from pattern#ABC
to next 2 liness/(Size=)bar/\1foo/
: MatchSize=bar
and replace withSize=foo
, using a capture group to avoid repeat of same String in search and substitution
You may also consider awk
to avoid repeating pattern and replacements N times if you have to replace N lines after matching pattern:
awk 'n-- {sub(/Size=bar/, "Size=foo")} /^#ABC$/ {n=2} 1' file
#ABC
oneSize=foo
twoSize=foo
threeSize=foo
Find and replace text containing a new line
In general you can used sed -z
which tells sed
to use the null-character to split lines. Assume you have the file text
containing
Hello World
This is a line
line1
line2
Hello World, again
line1
line2
end
Executing sed -z -e 's/line1\nline2/xxx/g' text
yields
Hello World
This is a line
xxx
Hello World, again
xxx
end
You can add *
(that is <space><star>
) to handle inconsistent white spaces.
In your specific case if you want to delete the second line you can use a block statement to advance to the next line and delete it if it matches the second line
sed -e '/line1/{n;/line2/d}' text
Replace next N lines before a first/second/third/... match including the match
Here's a BSD sed version (comment.sed):
/Text/, /}/ {
s|^|//|
/}/ {
:idle
n
b idle
}
}
The first line /Text/, /}/
is a regex address range. Every line within that that range (inclusive) will be commented out. At the end of this range, the second /}/
, we loop back to the idle
label consuming the rest of the file. Otherwise the address range would also comment out the second Text
block.
A one line version:
sed '/Text/, /}/ {s|^|//|; /}/ {:idle; n; b idle}}' input
To test:
diff expect <(sed -f comment.sed input) && echo ok
Replace text in file if previous line matches another text
One way to do it with sed
(tested using macOS's sed and GNU sed), would be this:
replace.sed
#!/usr/bin/env sed -Ef
/FooBarB/,/^FooBar/ {
s/(foo[[:space:]]*=[[:space:]]*).+/\1new-value/
}
Here's what it does:
/FooBarB/,/^FooBar/
matches a range of lines where the first line matches the regex/FooBarB/
and the last line matches the regex/^FooBar/
(which is the start of the next "group"). The comma between the two regexes is the syntax for range matching insed
.s/(foo[[:space:]]*=[[:space:]]*).+/\1new-value/
— [s]ubstitutes (in the matched range of lines) whatever matches the regex(foo[[:space:]]*=[[:space:]]*).+
with\1new-value
, where\1
references the first capturing group in the search regex. The search regex looks forfoo
followed by optional whitespace, followed by an=
sign, followed again by whitespace and then whatever else is there, which in your case is the old value.
You could do it all in just one line, but I wanted to show a version that's a bit more digestible (as far as sed
goes, in any case):
sed -E '/FooBarA/,/^FooBar/s/(foo[[:space:]]*=[[:space:]]*).+/\1new-value/' temp.md
Related Topics
How to Set Memory Limit for Oom Killer for Chrome
How to Convert Yyyymmddhhmmss to a Date Readable by 'Date'
Remove a Symlink to a Directory
How to Get the Start Time of a Long-Running Linux Process
How to Automatically Add User Account and Password with a Bash Script
How to Monitor the Thread Count of a Process on Linux
How to Use Xargs to Copy Files That Have Spaces and Quotes in Their Names
Optimize PDF Files (With Ghostscript or Other)
Centos 64 Bit Bad Elf Interpreter
Git Status Ignore Line Endings/Identical Files/Windows & Linux Environment/Dropbox/Meld
How to Use Arrow Keys Alone to Expand Tree Node in Package Explorer in Eclipse on Linux
Create Zip File and Ignore Directory Structure
Linux Shell Script to Add Leading Zeros to File Names
Change Path Permanently on Ubuntu
Nuget on Linux: Error Getting Response Stream