Linux SED脚本找到匹配模式的第一行并删除它

时间:2011-06-29 09:58:30

标签: linux full-text-search sed

我想创建一个sed命令,在文件中查找匹配模式的第一行,删除所有该行或将其全部替换为其他文本。我不想匹配所有的行,因为规则是匹配它的一部分。

我怎么能用sed做到这一点?

例如:

myline 1 is pretty
line 2 is ugly
myline 111 is nice

我想删除包含“1 is”的第一行

更新:我的行可能包含“/”和“<”之类的字符

此致 FAK

3 个答案:

答案 0 :(得分:7)

来自sed FAQ

sed '0,/RE/{//d;}' file        # delete only the first match
sed '0,/RE/s//to_that/' file   # change only the first match

如果您不使用GNU sed,请查看常见问题解答中的备选方案。

答案 1 :(得分:1)

我倾向于使用awk来完成更复杂的任务,它比sed更强大,具有适当的循环和选择结构(为了便于阅读,你可以将它压缩回一行,如果你希望):

pax$ echo '
xyz
myline 1 is pretty
line 2 is ugly
myline 111 is nice'  | awk '
     /1 is/ {if (f) {print} else {f = 1}}
    !/1 is/ {print}'

xyz
line 2 is ugly
myline 111 is nice

对于匹配模式(!/1 is/)的任何 行,它只会打印出来。

对于匹配模式的行,如果设置了标志f(它最初没有设置),它会全部打印出来。当标志未设置且遇到匹配的行时,它会设置标志并不打印它。这基本上会根据需要删除第一个匹配行。

如果你想修改第一个匹配的行而不是删除它,你只需在f = 1旁边插入代码来执行此操作,例如:

pax$ echo '
xyz
myline 1 is pretty
line 2 is ugly
myline 111 is nice'  | awk '
     /1 is/ {if (f) {print} else {f = 1;print "URK!!!"}}
    !/1 is/ {print}'

xyz
URK!!!
line 2 is ugly
myline 111 is nice

要在awk中使用shell变量,您可以使用-v选项将其作为真实awk变量传递:

pax$ export xyzvar=URK ; echo '
xyz
myline 1 is pretty
line 2 is ugly
myline 111 is nice'  | awk -vmyvar=$xyzvar '
     /1 is/ {if (f) {print} else {f = 1;print myvar}}
    !/1 is/ {print}'

xyz
URK
line 2 is ugly
myline 111 is nice

答案 2 :(得分:0)

你可以在没有sed的情况下完成它。 Bash脚本:

LINE=$(grep -n "$EXPR" "$FILE" |head -1 |cut -f1 -d:)
head -$(expr $LINE - 1 ) $FILE
tail +$(expr $LINE + 1 ) $FILE

只需声明$EXPR$FILE