您好,我正在尝试弄清楚如何从模式/单词字符串中选择文本文件中的一行,然后用新文本替换该行,并为每行更改添加递增的数字。
我计划使用 sed,但不知道如何为每行更改实现增加的数量。
之前和之后的目标:
之前的文字:
">text_1_lots of other bits of text"
other lines of text
">text_2_lots of other bits of text"
other lines of text
">text_3_lots of other bits of text"
other lines of text
之后的文字:
">text_1"
other lines of text
">text_2"
other lines of text
">text_3"
other lines of text
这是我到目前为止所拥有的:
sed -i "s/>text_*/>text_[0-n]/g"
我意识到这不起作用,因为[0-n]
和 通配符*
只是代表我想要做的事情,并且是我能想到实现这一目标的最接近的事情(尽管我知道这本质上是伪代码)
答案1
perl
可以使用与 类似的语法来完成此操作sed
,但允许直接评估替换索引,例如
perl -pe 's/>text_.*/sprintf "text_%d", ++$n/pe' file
也可以看看用顺序索引替换字符串。
但是,由于在您的情况下文本已经编号,因此通过捕获并重新替换它来修剪不需要的部分会更容易 - 例如
sed -E 's/(>text_[0-9]+).*/\1/' file
答案2
根据您对 sed 的尝试,您尝试匹配的模式似乎是">text_
并且您想要"
在其后附加一个数字和一个
这是可以用awk
.
awk 'BEGIN {cnt=1} /^">text_/ { gsub("_.*$","_"cnt++"\"",$0) } { print}'
例如
$ cat x
">text_lots of other bits of text"
other lines of text
">text_lots of other bits of text"
other lines of text
">text_lots of other bits of text"
other lines of text
$ awk 'BEGIN {cnt=1} /^">text_/ { gsub("_.*$","_"cnt++"\"",$0) } { print}' x
">text_1"
other lines of text
">text_2"
other lines of text
">text_3"
other lines of text
您可以更改搜索模式^"text_
来识别要更改的行,调用gsub()
将进行替换;在这种情况下,从行的第一行_
到行尾被替换为_
then 计数 then a"
答案3
我认为最简单的是使用 bash 或 perl。简单的 bash 示例应该可以帮助您解决可能更复杂的问题:
$ cat script
#!/bin/bash
i=1
while read a ; do
if [[ "$a" =~ "\">text_${i}".* ]]
then echo "\">text_${i}\"" ; i=$((i+1))
else echo "$a"
fi
done
$ cat input
">text_1_lots of other bits of text"
other lines of text
">text_2_lots of other bits of text"
other lines of text
">text_3_lots of other bits of text"
other lines of text
$ cat input | bash script
">text_1"
other lines of text
">text_2"
other lines of text
">text_3"
other lines of text
答案4
使用乐(以前称为 Perl_6)
~$ raku -pe 'state $i; s/^ \" \> text_ .* /"text_{++$i}"/;' file
或者:
~$ raku -pe 'state $i; s/^ \" \> text_ .* /{sprintf "\"text_%d\"", ++$i}/;' file
Raku 是 Perl 家族的一种编程语言。上面的第二个答案基本上是 @steeldriver 优秀 Perl5 代码的翻译。
简而言之,-pe
使用了 Raku 类似 sed 的自动打印命令行标志。 Raku 正则表达式中的非<alnum>
字符必须转义,但是正则表达式原子可以展开,因为它们可以容忍空格(等于 Perl 的\x
)。计数器变量$i
是state
d,这意味着它仅实例化一次(可以在此处使用 BEGIN 块,例如BEGIN my $i;
)。替换应该是不言自明的:Raku 代码插在{
…}
大括号内。
示例输入:
">text_A_lots of other bits of text"
other lines of text
">text_B_lots of other bits of text"
other lines of text
">text_C_lots of other bits of text"
other lines of text
示例输出:
"text_1"
other lines of text
"text_2"
other lines of text
"text_3"
other lines of text
https://docs.raku.org/language/regexes
https://docs.raku.org
https://raku.org