如何在特定模式(mv)上方2-3行插入内容?sed/awk方案求助
mv Occurrence Let's fix this step by step. The issue with your existing commands is that they don't properly buffer the preceding lines to insert above mv, and they don't ensure the insertion happens only once. Here are reliable solutions for both 2-line and 3-line offsets:
Solution 1: Using Awk (Most Readable & Flexible)
Awk makes it easy to maintain a buffer of recent lines, which is perfect for this task. This script will insert your desired line once, 2 lines above the first mv it encounters:
BEGIN { buffer_size = 2 # Change this to 3 if you need 3 lines above mv line_count = 0 inserted = 0 } !inserted { # If we hit the first mv line if ($0 ~ /mv/) { print "your_new_line_content" # Replace with your actual line # Print the buffered lines for (i = 1; i <= line_count; i++) { print buffer[i] } print $0 # Print the mv line itself inserted = 1 # Mark insertion as done to avoid repeats next } # Add current line to buffer buffer[++line_count] = $0 # If buffer exceeds size, print the oldest line and shift buffer if (line_count > buffer_size) { print buffer[1] for (i = 1; i < line_count; i++) { buffer[i] = buffer[i+1] } line_count-- } } # After insertion, just print all remaining lines normally inserted { print $0 } # If mv was never found, print any remaining buffered lines END { if (!inserted) { for (i = 1; i <= line_count; i++) { print buffer[i] } } }
How to Use:
- Replace
your_new_line_contentwith the line you want to insert. - Adjust
buffer_sizeto 3 if you need the line inserted 3 lines abovemv. - Run it with:
awk -f script.awk your_file.txt - To edit the file in-place (like sed's
-i), use:awk -f script.awk your_file.txt > temp && mv temp your_file.txt
Solution 2: Using Sed (For Those Preferring Sed Syntax)
Sed requires using the hold space to buffer lines. Here's a command that inserts a line once, 2 lines above the first mv:
/mv/{ # Check if we have lines in hold space x /./{ x # Split hold space into two lines (for 2-line offset) s/\(.*\)\n\(.*\)/your_new_line_content\n\1\n\2/ p # Clear hold space to avoid reinserting x s/.*// x } x b end } # Collect lines into hold space H $b end :end # Print remaining content if mv wasn't found x /./p ' your_file.txt
Adjust for 3 Lines Above:
To insert 3 lines above mv, modify the split line to:s/\(.*\)\n\(.*\)\n\(.*\)/your_new_line_content\n\1\n\2\n\3/
In-Place Edit:
Add -i (or -i.bak for a backup) to the sed command to edit the file directly:sed -i.bak -e '...' your_file.txt
Why Your Previous Commands Failed:
- Your sed command
sed -i '/mv/2i \this' fileuses invalid syntax—2iisn't a valid sed command. Theicommand inserts before the matched line, but it can't reference preceding lines directly without buffering. - Your awk attempt didn't maintain a buffer of prior lines, so it couldn't insert above the
mvline correctly.
内容的提问来源于stack exchange,提问作者Pablor

