如何在diff结果中匹配模式并打印目标行及跨多行关联内容?
Got it, let's break down your two requirements and tackle them one by one with practical shell-based solutions—these are common text-processing tasks, so we'll use tools like sed, awk, and grep that you probably already have available:
If you want to start scanning from a specific line (say, line 10) and pull context around lines that match your pattern, here are two reliable approaches:
Option 1: Quick grep + sed combo
Use sed to slice the file starting at your target line, then pipe the result to grep to grab matching lines and their context:
# Example: Start at line 10, find lines with "critical", and print 3 lines before/after each match sed -n '10,$p' your_file.txt | grep -C 3 "critical"
-C 3sets 3 lines of context; adjust the number to fit your needs.sed -n '10,$p'extracts everything from line 10 to the end of the file.
Option 2: Flexible awk script
For more control (like avoiding duplicate context or adding separators between matches), use this awk script:
awk -v start_line=10 -v pattern="critical" -v context=2 ' NR >= start_line { lines[NR] = $0 # Store lines starting from the target line if ($0 ~ pattern) { # Print context around the matched line for (i = NR - context; i <= NR + context; i++) { if (lines[i] != "") print lines[i] } print "---" # Separator for readability } }' your_file.txt
This script tracks lines starting from your specified row, and when it hits a match, it prints the configured number of lines before and after it.
First, we need to check if line 7 was modified in the diff, then extract the changed line and the entire "Tags" block (even if it spans unknown lines). Here's a step-by-step solution:
Step 1: Check if line 7 was modified
We'll use unified diff format (diff -u) to easily spot line number changes, then check if line 7 is in the modified range:
# Compare old and new files, check if line 7 is in the diff if diff -u old_file.txt new_file.txt | grep -q "^@@.*+7\|^@@.*-7"; then # Print the modified line 7 (from the new file) echo "Changed line 7:" sed -n '7p' new_file.txt # Print the full Tags block (adjust the end pattern to match your actual Tags syntax) echo -e "\nFull Tags block:" # Extract from the line containing "Tags" to the line with the closing bracket (modify as needed) sed -n '/"Tags"/,/]/p' new_file.txt fi
- The
grep -qcheck looks for diff header lines (@@) that reference line 7 in either the old (-7) or new (+7) file. - The
sed -n '/"Tags"/,/]/pline grabs everything from the first line with"Tags"to the line with a closing bracket (]). Adjust the end pattern (like/}/or/".*",/) to match how your Tags block ends.
Alternative: awk for dynamic Tags block detection
If your Tags block doesn't have a predictable end marker, use this awk script to print line 7 and the full Tags block:
awk -v target_line=7 ' # Print the modified line 7 NR == target_line { print "Changed line 7:", $0 print "" } # Enter Tags block mode when we hit "Tags" /"Tags"/ { in_tags = 1 } # Print lines while in Tags block mode in_tags { print } # Exit Tags block mode when we hit a closing quoted string (adjust as needed) /".*",/ || /".*"\)/ { in_tags = 0 } ' new_file.txt
This will print line 7, then start printing lines as soon as it sees "Tags", stopping when it hits a line with a closed quoted string (tweak the exit condition to match your data format).
内容的提问来源于stack exchange,提问作者TryTryAgain

