Sed用行号替换模式

时间:2012-09-19 14:18:57

标签: sed awk gawk

我需要用当前行号替换模式###

我设法在AWK和SED的下一行打印。

sed -n "/###/{p;=;}" file打印到下一行,没有p;,它会替换整行。

sed -e "s/###/{=;}/g" file过去常常有道理,因为=;会返回匹配模式的行号,但它会返回文本{=;}

我想念的是什么?我知道这是一个愚蠢的问题。我在sed手册中找不到这个问题的答案,但不太清楚。

如果可能的话,请指出我错过了什么,以及让它成功的原因。谢谢

7 个答案:

答案 0 :(得分:8)

简单awk oneliner:

awk '{gsub("###",NR,$0);print}'

答案 1 :(得分:4)

鉴于the limitations of the = 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没有简单的方法,因为=命令和r和GNU扩展R命令都不会读取文件进入模式空间,而是直接将行附加到输出,因此无法以任何方式修改文件的内容。因此管道到另一个sed命令。

如果test的内容是

fooo
bar ### aa
test
zz ### bar

以上将产生

fooo
bar 2 aa
test
zz 4 bar

答案 2 :(得分:2)

Lev Levitsky 所述,一次调用sed是不可能的,因为行号直接发送到标准输出。

您可以为您编写sed脚本,并在两次通过中进行替换:

infile中

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

答案 3 :(得分:2)

这可能适合你(GNU sed):

sed = file | sed 'N;:a;s/\(\(.*\)\n.*\)###/\1\2/;ta;s/.*\n//'

答案 4 :(得分:1)

这样可以吗?

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

答案 5 :(得分:0)

单线修改FILE,用相应的行号替换LINE:

uintptr_t temporary = value;
return ~temporary;

答案 6 :(得分:0)

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/