我有一个类似的文件:
# ID 1
blah blah
blah blah
$ description 1
blah blah
# ID 2
blah
$ description 2
blah blah
blah blah
如何使用sed命令删除#
和$
行之间的所有行?结果将变为:
# ID 1
$ description 1
blah blah
# ID 2
$ description 2
blah blah
blah blah
您能否请您解释一下?
答案 0 :(得分:47)
使用此sed命令实现:
sed '/^#/,/^\$/{/^#/!{/^\$/!d}}' file.txt
Mac用户(防止extra characters at the end of d command
错误)需要在结束括号前添加分号
sed '/^#/,/^\$/{/^#/!{/^\$/!d;};}' file.txt
# ID 1
$ description 1
blah blah
# ID 2
$ description 2
blah blah
blah blah
/^#/,/^\$/
会将以#
开头的行与以$
开头的行之间的所有文字进行匹配。 ^
用于行首角色。 $
是一个特殊字符,因此需要进行转义。/^#/!
表示如果行的开头不是#
/^$/!
表示如果行的开头不是$
d
表示删除总体而言,它首先匹配^#
到^\$
的所有行,然后匹配那些找到不匹配的行 ^#
和< strong>不匹配 ^\$
并使用d
删除它们。
答案 1 :(得分:32)
$ cat test
1
start
2
end
3
$ sed -n '1,/start/p;/end/,$p' test
1
start
end
3
$ sed '/start/,/end/d' test
1
3
答案 2 :(得分:5)
sed的另一种方法:
sed '/^#/,/^\$/{//!d;};' file
/^#/,/^\$/
:从#
开始到从$
开始的下一行//!d
:删除除地址模式匹配的所有行答案 3 :(得分:5)
一般来说,如果您的文件内容为 abcde ,其中 a 部分位于模式 b 之前,则部分 c 在模式 d 之前,然后是 e 部分,然后应用以下sed
命令,您将得到以下结果。
在此演示中,输出由=> abcde
表示,其中字母显示输出中的哪些部分。因此,ae
仅显示 a 和 e 部分的输出,ace
将是部分 a , c , e 等
请注意,如果输出中出现b
或d
,则会出现这些模式(即,它们被视为输出中的部分)。
另外,请勿将/d/
模式与命令d
混淆。在这些演示中,命令始终处于最后。模式总是在//
之间。
sed -n -e '/b/,/d/!p' abcde
=&gt; AE sed -n -e '/b/,/d/p' abcde
=&gt; BCD sed -n -e '/b/,/d/{//!p}' abcde
=&gt; çsed -n -e '/b/,/d/{//p}' abcde
=&gt; BD sed -e '/b/,/d/!d' abcde
=&gt; BCD sed -e '/b/,/d/d' abcde
=&gt; AE sed -e '/b/,/d/{//!d}' abcde
=&gt; ABDE sed -e '/b/,/d/{//d}' abcde
=&gt;王牌答案 4 :(得分:3)
我很久以前做过这样的事情,就像是:
sed -n -e "1,/# ID 1/ p" -e "/\$ description 1/,$ p"
类似于:
-n
取消所有输出-e "1,/# ID 1/ p"
从第一行执行,直到您的模式和p(打印)-e "/\$ description 1/,$ p"
从第二个模式执行直到结束并执行p(打印)。我可能错了一些字符串上的转义,所以请仔细检查。
答案 5 :(得分:0)
下面的示例删除了 “ if” 和 “ end if” 之间的行。
将扫描所有文件,并删除两个匹配模式之间的行(包括它们)。
IFS='
'
PATTERN_1="^if"
PATTERN_2="end if"
# Search for the 1st pattern in all files under the current directory.
GREP_RESULTS=(`grep -nRi "$PATTERN_1" .`)
# Go through each result
for line in "${GREP_RESULTS[@]}"; do
# Save the file and line number where the match was found.
FILE=${line%%:*}
START_LINE=`echo "$line" | cut -f2 -d:`
# Search on the same file for a match of the 2nd pattern. The search
# starts from the line where the 1st pattern was matched.
GREP_RESULT=(`tail -n +${START_LINE} $FILE | grep -in "$PATTERN_2" | head -n1`)
END_LINE="$(( $START_LINE + `echo "$GREP_RESULT" | cut -f1 -d:` - 1 ))"
# Remove lines between first and second match from file
sed -e "${START_LINE},${END_LINE}d;" $FILE > $FILE
done