使用Sed替换模式和行号

10

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

我已经成功使用AWK和SED在下一行打印了文本。

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

以前我认为sed -e "s/###/{=;}/g" file 是正确的,因为 =; 打印匹配模式的行号,但是它会返回文本 {=;}

我错了吗?我知道这是一个愚蠢的问题。我在Sed手册中找不到答案,不太清楚。

如果可能,请指出我的错误,并告诉我如何解决。谢谢。


由于“=”命令只在标准输出中打印,因此您无法将行号打印在与模式相同的行上。 - Lev Levitsky
用 Awk 可以实现吗? - ghaschel
我测试了每一个答案,最好的是@twalberg的awk。谢谢大家。 - ghaschel
7个回答

10

使用简单的awk一行命令:

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

@Thor 也许我做出了不同的假设 - 那不仅仅是把行号放在行首吗?我理解 OP 的意思是 "###" 可能出现在任何位置,因此需要使用 gsub()。尽管在第二次阅读时,似乎将数字放在行首可能是想要的... - twalberg

5

鉴于= 命令的限制,我认为将任务分为两个(实际上是三个)部分更容易。使用 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

4
这可能适用于您(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//'

你能解释一下 sed 的模式吗? - Yohan W. Dunon

3

正如 Lev Levitsky 所指出的那样,使用一次 sed 命令无法实现此操作,因为行号直接发送到标准输出。

您可以让 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

1

这个可以吗?

kent$  echo "a
b
c
d
e"|awk '/d/{$0=$0" "NR}1'
a
b
c
d 4
e

如果匹配模式为“d”,则在行末附加行号。

编辑

哦,你想替换模式而不是附加行号...看一下新的命令:

kent$  echo "a
b
c
d
e"|awk '/d/{gsub(/d/,NR)}1'
a
b
c
4
e

而且这行代码也可以这样写:awk '1+gsub(/d/,NR)' file


OP需要用行号替换模式,这并不完全是答案。 - Lev Levitsky

1

一行代码可以直接修改文件,将LINE替换为对应的行号:

seq 1 `wc -l FILE | awk '{print $1}'` | xargs -IX sed -i 'X s/LINE/X/' FILE

对于OSX版本的sed,我不得不进行修改,因为-i参数的处理方式有所不同。https://dev59.com/Smcs5IYBdhLWcg3w5H9a#63854797 - Ben Page

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接