在文中Sed - 替换文件中单词的前 k 个实例,用户建议:
sed 's/old/new/;s/old/new/;s/old/new/;s/old/new/;s/old/new/' filename
作为替换一行中单词的前 k 个实例的方法。对于用新的替换旧的前 k 个实例的问题来说,这似乎是一个不优雅的解决方案。还有其他方法讨论,做其他事情。但是对于使用 sed 替换一行中单词的前 k 次出现的问题,没有其他(或没有其他优雅的)解决方案。
长/博士:
我有一大堆我称之为“slugs”的项目,它们对于我想要跟踪的各种奇怪的小事情非常有帮助。它们看起来像这样:
#slug YYYY/MM/DD d hhmm field1 field2 field3 notes
我将它们保存在一系列注明日期的文件中。然后我将文件通过 grep | sed | awk 链从数据生成报告。假设我邻居的狗在吠叫,让我彻夜难眠。每当我听到狗叫时,我都会记下时间,然后将其记录在我的日志文件中。
#bark 2016/04/06 W 0214 0232 Police showed up!
一段时间后,我将存储一个数据库,希望我会注意到一些趋势,比如......谁知道什么......狗在满月时吠叫什么的。小程序链如下所示:
grep "^#[Bb][Aa]" 2014* 2015* 2016* |\
sed 's/ /|/;s/ /|/;s/ /|/;s/ /|/;s/ /|/' |\
awk {something or other} >\
barking-dog-report
所以,我的问题是 sed 部分:
sed 's/ /|/;s/ /|/;s/ /|/;s/ /|/;s/ /|/'
这在这里翻译为“将前五个空格替换为管道”。我在 awk 中使用管道作为字段分隔符。像这样的命令s/ /|/5
不起作用,它只会将每行上的第五个空格更改为管道。我只是觉得这一系列 sed 命令看起来很可笑。它不是全局替换s/ /|/g
,因为我想将空格保留为注释部分的空格(而不是将它们用作字段分隔符)。
答案1
您可以将五个sed
命令合并为一个(但这并不会使其变得更短):
sed 's/^\([^ ]*\) \([^ ]*\) \([^ ]*\) \([^ ]*\) \([^ ]*\) \(.*\)/\1|\2|\3|\4|\5|\6/'
但是您可以将grep
搜索放入脚本中sed
,以将 shell 命令减少 1(此处使用原始替换命令):
sed -n '/^#[Aa][Bb]/{s/ /|/;s/ /|/;s/ /|/;s/ /|/;s/ /|/;p;}' files |\
awk '...' > report