如何限制Sed替换范围:仅在指定关键词前移除注释与空白行?
Problem
I have multiple files where I need to clean up lines before a specific keyword: remove # comments (both line-leading and inline), ; inline comments, and blank lines. However, the keyword's line number isn't fixed, and I need to preserve everything from the keyword line onward—including comments, blank lines, and original content.
My current sed command modifies the entire file, which isn't what I want:
sed -i -e 's/#.*$//' -e 's/;.*$//' -e '/^$/d' file
Sample Input File:
# string1 # string2 some string ; string3 ; string4 #### <Keyword_Keep_this_line_and_comments_white_space_after_this> # More comments that need to be here ; etc.
Desired Output:
some string #### <Keyword_Keep_this_line_and_comments_white_space_after_this> # More comments that need to be here ; etc.
Solution
You can use sed's pattern-based address range control to restrict your cleanup operations only to lines before the keyword. Here's the adjusted command:
sed -i -e '/<Keyword_Keep_this_line_and_comments_white_space_after_this>/!{ s/#.*$//; s/;.*$//; /^$/d; }' file
How It Works
Let's break down the command step by step:
/<Keyword...>/!{ ... }: This tells sed to only run the commands inside the curly braces on lines that do NOT match the keyword. Lines that match the keyword (and all lines after it) are left untouched.- Inside the braces, we run your original cleanup rules, but only on non-keyword lines:
s/#.*$//: Removes all text from the first#to the end of the line (handles both line-leading and inline#comments)s/;.*$//: Removes all text from the first;to the end of the line (handles inline;comments)/^$/d: Deletes any lines that become blank after the above two substitutions
Handling Special Characters in the Keyword
If your keyword contains regex-special characters (like #, <, >), use GNU sed's \Q and \E to escape them so they're treated as literal text:
sed -i -e '/\Q#### <Keyword_Keep_this_line_and_comments_white_space_after_this>\E/!{ s/#.*$//; s/;.*$//; /^$/d; }' file
Batch Processing Multiple Files
To apply this to all .txt files in a directory, use a wildcard:
sed -i -e '/<Keyword_Keep_this_line_and_comments_white_space_after_this>/!{ s/#.*$//; s/;.*$//; /^$/d; }' *.txt
内容的提问来源于stack exchange,提问作者p.la

