我需要###
用当前行号替换模式。
我设法用 AWK 和 SED 在下一行打印。
sed -n "/###/{p;=;}" file
打印到下一行,如果没有p;
,它将替换整行。
sed -e "s/###/{=;}/g" file
曾经在我的脑海中有意义,因为它=;
返回匹配模式的行号,但它会返回我的文本{=;}
我错过了什么?我知道这是一个愚蠢的问题。我在 sed 手册中找不到这个问题的答案,不太清楚。
如果可能的话,请指出我缺少什么,以及如何让它发挥作用。谢谢
简单awk
的oneliner:
awk '{gsub("###",NR,$0);print}'
鉴于command的限制=
,我认为将工作分为两部分(实际上是三部分)更容易。使用 GNU sed
,您可以:
$ sed -n '/###/=' test > lineno
然后像
$ sed -e '/###/R lineno' test | sed '/###/{:r;N;s/###\([^\n]*\n\)\([^\n]*\)/\2\1/;tr;:c;s/\n\n/\n/;tc}'
恐怕没有简单的方法,sed
因为除了=
命令之外,ther
和 GNU 扩展R
命令不会将文件读入模式空间,而是直接将行附加到输出中,因此文件的内容不能以任何方式修改。因此管道到另一个sed
命令。
如果内容test
是
fooo
bar ### aa
test
zz ### bar
以上会产生
fooo
bar 2 aa
test
zz 4 bar
这可能对您有用(GNU sed):
sed = file | sed 'N;:a;s/\(\(.*\)\n.*\)###/\1\2/;ta;s/.*\n//'
使用 cat 的替代方法:
cat -n file | sed -E ':a;s/^(\s*(\S*)\t.*)###/\1\2/;ta;s/.*\t//'
正如Lev Levitsky所指出的,这不可能通过一次 sed 调用来实现,因为行号直接发送到标准输出。
您可以 sed 为您编写一个 sed 脚本,然后分两遍进行替换:
文件
a
b
c
d
e
###
###
###
a
b
###
c
d
e
###
找到包含该模式的行:
sed -n '/###/=' infile
输出:
6
7
8
11
15
将其通过管道传输到 sed 脚本中,编写一个新的 sed 脚本:
sed 's:.*:&s/###/&/:'
输出:
6s/###/6/
7s/###/7/
8s/###/8/
11s/###/11/
15s/###/15/
执行:
sed -n '/###/=' infile | sed 's:.*:&s/^/& \&/:' | sed -f - infile
输出:
a
b
c
d
e
6
7
8
a
b
11
c
d
e
15
这个可以吗 ?
kent$ echo "a
b
c
d
e"|awk '/d/{$0=$0" "NR}1'
a
b
c
d 4
e
如果匹配模式“d”,则在行尾附加行号。
编辑
哦,你想替换模式而不是附加行号......看看新的cmd:
kent$ echo "a
b
c
d
e"|awk '/d/{gsub(/d/,NR)}1'
a
b
c
4
e
该行也可以这样写: awk '1+gsub(/d/,NR)' file
one-liner 将 FILE 修改到位,将 LINE 替换为对应的行号:
seq 1 `wc -l FILE | awk '{print $1}'` | xargs -IX sed -i 'X s/LINE/X/' FILE
继https://stackoverflow.com/a/53519367/29924
如果您在 osx 上尝试此操作,则 sed 的版本不同,您需要执行以下操作:
seq 1 `wc -l FILE | awk '{print $1}'` | xargs --verbose -IX sed -i bak "X s/__line__/X/" FILE
见https://markhneedham.com/blog/2011/01/14/sed-sed-1-invalid-command-code-r-on-mac-os-x/