我想创建一个sed命令,在文件中查找匹配模式的第一行,删除所有该行或将其全部替换为其他文本。我不想匹配所有的行,因为规则是匹配它的一部分。
我怎么能用sed做到这一点?
例如:
myline 1 is pretty
line 2 is ugly
myline 111 is nice
我想删除包含“1 is”的第一行
更新:我的行可能包含“/”和“<”之类的字符
此致 FAK
答案 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
。