出于某种原因,我似乎找不到一个直截了当的答案,我现在有点时间紧张。如何使用sed命令在匹配特定字符串的第一行之后插入选择的文本行呢?我有……
CLIENTSCRIPT="foo"
CLIENTFILE="bar"
我想在CLIENTSCRIPT=行之后插入一行,导致…
CLIENTSCRIPT="foo"
CLIENTSCRIPT2="hello"
CLIENTFILE="bar"
出于某种原因,我似乎找不到一个直截了当的答案,我现在有点时间紧张。如何使用sed命令在匹配特定字符串的第一行之后插入选择的文本行呢?我有……
CLIENTSCRIPT="foo"
CLIENTFILE="bar"
我想在CLIENTSCRIPT=行之后插入一行,导致…
CLIENTSCRIPT="foo"
CLIENTSCRIPT2="hello"
CLIENTFILE="bar"
当前回答
Sed命令,适用于MacOS(至少,OS 10)和Unix(即。不像Gilles(目前被接受)那样需要gnu sed):
sed -e '/CLIENTSCRIPT="foo"/a\'$'\n''CLIENTSCRIPT2="hello"' file
这可以在bash中工作,也许其他shell也知道$'\n'计算引用样式。所有东西都可以写在一条线上 旧的/POSIX sed命令。如果可能有多行匹配CLIENTSCRIPT="foo"(或类似的代码),并且您希望第一次只添加额外的行,您可以按以下方式重新工作:
sed -e '/^ *CLIENTSCRIPT="foo"/b ins' -e b -e ':ins' -e 'a\'$'\n''CLIENTSCRIPT2="hello"' -e ': done' -e 'n;b done' file
(这会在行插入代码之后创建一个循环,循环遍历文件的其余部分,再也不会回到第一个sed命令)。
您可能会注意到,我在匹配模式中添加了一个'^ *',以防该行出现在注释中,或者被缩进。它不是100%完美的,但涵盖了其他一些可能常见的情况。根据需要调整…
这两种解决方案还解决了一个问题(对于添加一行的通用解决方案),即如果新插入的行包含未转义的反斜杠或&号,sed将解释它们,结果可能不一样,就像\n是- eg一样。\0将是匹配的第一行。尤其方便的是,如果你添加的一行来自一个变量,否则你必须先转义所有的东西之前使用${var//},或另一个sed语句等。
这种解决方案在脚本中稍微不那么混乱(但是引号和\n不容易阅读),当您不想在一个有缩进行的函数中将a命令的替换文本放在一行的开头时。我已经利用了$'\n'被shell计算为换行,它不是常规的'\n'单引号值。
虽然它已经足够长了,但我认为perl/甚至awk可能会胜出,因为它更具可读性。
其他回答
也许现在给出答案有点晚了,但我发现上面的一些解决方案有点麻烦。
我尝试了简单的字符串替换sed和它工作:
sed 's/CLIENTSCRIPT="foo"/&\nCLIENTSCRIPT2="hello"/' file
&符号反映匹配的字符串,然后添加\n和新行。
如前所述,如果你想就地完成:
sed -i 's/CLIENTSCRIPT="foo"/&\nCLIENTSCRIPT2="hello"/' file
另一件事。您可以使用表达式进行匹配:
sed -i 's/CLIENTSCRIPT=.*/&\nCLIENTSCRIPT2="hello"/' file
希望这对大家有所帮助
I had to do this recently as well for both Mac and Linux OS's and after browsing through many posts and trying many things out, in my particular opinion I never got to where I wanted to which is: a simple enough to understand solution using well known and standard commands with simple patterns, one liner, portable, expandable to add in more constraints. Then I tried to looked at it with a different perspective, that's when I realized i could do without the "one liner" option if a "2-liner" met the rest of my criteria. At the end I came up with this solution I like that works in both Ubuntu and Mac which i wanted to share with everyone:
insertLine=$(( $(grep -n "foo" sample.txt | cut -f1 -d: | head -1) + 1 ))
sed -i -e "$insertLine"' i\'$'\n''bar'$'\n' sample.txt
在第一个命令中,grep查找包含“foo”的行号,cut/head选择第一次出现的行号,算术运算将第一次出现的行号加1,因为我想在出现之后插入。 在第二个命令中,它是一个就地文件编辑,“i”用于插入:一个ansi-c引用的新行,“bar”,然后另一个新行。结果是在“foo”行之后添加了包含“bar”的新行。这两个命令都可以扩展为更复杂的操作和匹配。
awk变体:
awk '1;/CLIENTSCRIPT=/{print "CLIENTSCRIPT2=\"hello\""}' file
尝试使用GNU sed执行此操作:
sed '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file
如果你想替换在原地,使用
sed -i '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file
输出
CLIENTSCRIPT="foo"
CLIENTSCRIPT2="hello"
CLIENTFILE="bar"
Doc
查看sed文档并搜索\a(追加)
Sed命令,适用于MacOS(至少,OS 10)和Unix(即。不像Gilles(目前被接受)那样需要gnu sed):
sed -e '/CLIENTSCRIPT="foo"/a\'$'\n''CLIENTSCRIPT2="hello"' file
这可以在bash中工作,也许其他shell也知道$'\n'计算引用样式。所有东西都可以写在一条线上 旧的/POSIX sed命令。如果可能有多行匹配CLIENTSCRIPT="foo"(或类似的代码),并且您希望第一次只添加额外的行,您可以按以下方式重新工作:
sed -e '/^ *CLIENTSCRIPT="foo"/b ins' -e b -e ':ins' -e 'a\'$'\n''CLIENTSCRIPT2="hello"' -e ': done' -e 'n;b done' file
(这会在行插入代码之后创建一个循环,循环遍历文件的其余部分,再也不会回到第一个sed命令)。
您可能会注意到,我在匹配模式中添加了一个'^ *',以防该行出现在注释中,或者被缩进。它不是100%完美的,但涵盖了其他一些可能常见的情况。根据需要调整…
这两种解决方案还解决了一个问题(对于添加一行的通用解决方案),即如果新插入的行包含未转义的反斜杠或&号,sed将解释它们,结果可能不一样,就像\n是- eg一样。\0将是匹配的第一行。尤其方便的是,如果你添加的一行来自一个变量,否则你必须先转义所有的东西之前使用${var//},或另一个sed语句等。
这种解决方案在脚本中稍微不那么混乱(但是引号和\n不容易阅读),当您不想在一个有缩进行的函数中将a命令的替换文本放在一行的开头时。我已经利用了$'\n'被shell计算为换行,它不是常规的'\n'单引号值。
虽然它已经足够长了,但我认为perl/甚至awk可能会胜出,因为它更具可读性。