仅保留前导空格,仅替换第一个匹配的行

时间:2015-10-28 10:47:43

标签: unix sed

我有一个文件,其中包含以下句子:

"cutoffTime": "20151024000000"

我想使用sed或grep来查找以cutoffTime开头的行, 然后用另一个字符串替换整行,例如:

"startTime" : "20151028000000"

编者注:

在问题之后出现了两个附加要求 - 并且几个答案 - 首次发布,标题现在反映了它们:

  • 在要替换的行的开头保留前导空格(或至少是制表符)。

  • 仅替换第一个匹配行。

4 个答案:

答案 0 :(得分:3)

要在行的开头保留前导空格

sed 's/^\([[:blank:]]*\)"cutoffTime":.*$/\1"startTime" : "20151028000000"/' file
  • ^\([[:blank:]]*\)捕获空格和制表符的任意组合(如果存在),位于该行的开头,并将其预先添加到替换行(通过\1,即对第一个(也是唯一的)捕获的引用正则表达式中的组,实际上保留了原始行中的前导空格。

也只替换第一个匹配:解决方案的复杂性取决于所使用的sed实现:

请注意,在//s//)格式下面的两个解决方案中 - 即省略正则表达式 - 意味着最近应用的正则表达式是隐含地重用。 功能

  • GNU sed
sed '0,/^\([[:blank:]]*\)"cutoffTime":.*$/ s//\1"startTime" : "20151028000000"/' file

0,/.../是一个 GNU sed扩展,允许正则表达式终止范围,即使它与第一个匹配< / em> line(使用1不会这样做,因为它总是开始第一行的范围,然后才开始在上查找正则表达式后续的行。实际上,这会将范围限制为文件的开头,直到正则表达式的第一次出现,无论它出现在何处,并且只替换该事件。

  • 仅限POSIX功能sed,例如 BSD sed(也用于OS X):
replacement='"startTime" : "20151028000000"'
sed -e '1 s/^\([[:blank:]]*\)"cutoffTime":.*$/\1'"$replacement"'/; t' \
    -e '1,// s//\1'"$replacement"'/' file

由于0,/.../功能不是POSIX的一部分,匹配可以在第一行行的情况必须单独处理,因此上面的第一个只在{{ 1}}用于匹配和替换; 1然后有效地从第2行看到第一个后续匹配并替换。请注意,如果执行了替换,第一次替换后的1,//调用将结束脚本周期,这意味着永远不会输入范围t。实际效果是,只有第一次出现的正则表达式才会发生替换,无论第一次出现的是什么。

答案 1 :(得分:2)

根据OP更新的查询使用这样来查找和替换第一次出现,如下所示;

sed '0,/^"cutoffTime":.*/{s/^"cutoffTime":.*/"startTime" : "20151028000000"/}' file 

这将改变上面第一个出现的模式。

要在源文件中替换,请使用-i

sed -i '0,/^"cutoffTime":.*/{s/^"cutoffTime":.*/"startTime" : "20151028000000"/}' file 

<强>解释

sed '0,/<pattern>/{s/<pattern>/<replacement>/}' file

<强>输出:

$ sed '0,/^"cutoffTime":.*/{s/^"cutoffTime":.*/"startTime" : "20151028000
000"/}' file1

"startTime" : "20151028000000"
"cutoffTime": "20151024000000"
"cutoffTime": "20151024000000"

答案 2 :(得分:1)

使用sed

sed 's/^"cutoffTime":.*/"startTime" : "20151028000000"/' file

并检查结果。如果要修改原始文件

sed -i .bak 's/^"cutoffTime":.*/"startTime" : "20151028000000"/' file
  • s命令的第一部分用替换^"cutoffTime":.*替换第一个表达式("startTime" : "20151028000000")。

  • 表达式匹配行^的开头,后跟您的文字"cutoffTime":,后跟任何重复0次或更多次的字符(.*

答案 3 :(得分:1)

EMPID, EMPNAME, DATEOFJOIN, PREVIOUS_EXP, DESIGNATION, Location EMPID, Email, Mobile EMPID, MANAGER EMPID, IMAGE 不支持-i选项时,您可以使用sed

ed

编辑:改变OP的要求,下面的新解决方案。
您可以使用替换字符串。您可以使用ed -s request << EOF ,s/^"cutoffTime":.*/"startTime" : "20151028000000"/ w q EOF 之类的东西来练习REGEX 如果您不想在该行的开头匹配,只需删除特殊cat request | sed 's/my_practicum/my_solution/'即可。当你只想改变第一场比赛时,你应该跳到正确的线。在下面的解决方案中,我将重复搜索字符串,因此如果找不到匹配项,则不会替换任何内容。

^

如果要保留前导字符,请更改子行:

ed -s request  << EOF
/cutoffTime
s/.*cutoffTime.*/"startTime" : "20151028000000"/
w
q
EOF