如何在 linux 命令行中用多个文件中的计数器附加值替换重复字符串



我们如何通过将字符串"string"替换为计数器递增值来修改现有文件,如下所示。

注意1:跳过第一个"string"注意2:此外,"字符串"不会在一行中出现超过一次。注3:foo"string"bar->foo"string"1bar是正确的

File1("string"在文件内任意行中出现一次(

some text
"string" here

File2("string"在文件内任意行中出现三次(

some text
"string" here
some more
text "string"
why "string"

File3("string"不会出现在文件内的任何行中(

some text
why here
some more>
text pttn
why pttn

File4("string"在文件内任意行出现一次(

some "string"
no here

如何将"string"替换为"string"1"string"2"string"3等?

预期输出:

文件1

some text
"string" here

文件2

some text
"string"1 here
some more
text "string"2
why "string"3

文件3

some text
why here
some more
text pttn
why pttn

文件4

some "string"4
no here

您的问题仍然不清楚,但这可能是您要查找的:

$ awk -v str='"string"' '
BEGIN { lgth = length(str) }
pos=index($0,str) {
$0 = substr($0,1,pos+lgth-1) cnt substr($0,pos+lgth)
cnt++
}
1' file{1,2,3,4}
some text
"string" here
some text
"string"1 here
some more
text "string"2
why "string"3
some text
why here
some more
text pttn
why pttn
some "string"4
no here

只需添加-i inplace(使用 GNU awk(即可更改输入文件而不是打印输出。上面假设您需要文字字符串匹配,并且该字符串不需要通过空格、标点或其他任何内容与其他文本分隔。

未经测试

gawk -i inplace -v p="pattern" '
{for (i=1; i<=NF; i++) if ($i == p) {$i = p n; n++}; print}
' File{1,2,3,4}

如果您想将输出保存到Input_file中,以下可能会对您有所帮助。

gawk -i inplace -v INPLACE_SUFFIX=.bak -v val="-1" '/pattern/{val++} {val=val==0?"":val;sub(/pattern/,"&"val)} 1' File1 File2 File3 File4

现在也添加一个非一个衬里形式的解决方案。

gawk -i inplace -v INPLACE_SUFFIX=.bak -v val="-1" '
/pattern/{
val++}
{
val=val==0?"":val;
sub(/pattern/,"&"val)}
1' File1 File2 File3 File4

这可能对你有用(GNU sed(:

sed -nr '/"string"/!b;x;/./!{s/^/0/;x;ba};:b;s/9(_*)$/_1/;tb;s/^(_*)$/01/;s/$/n0123456789/;s/(.)(_*)n.*1(.).*/32/;y/_/0/;x;G;s/("string")(.*)n(.*)/132/;:a;W /dev/stdout' File? |
sed -i.bak -e '/"string"/!b;R /dev/stdin' -e 'd' File?

创建所有修改字符串的文件,更新文件,一次更新一个修改后的字符串。

sed 的第一次调用获取包含"string"的每一行并将其递增(第一个除外(并将其输出到stdout

sed 的第二次调用将包含"string"的每一行替换为stdin中的下一行。文件通过-i.bak选项内联更新,这将创建后缀为.bak的原始文件的备份。

注:注:这假定每行上只出现一次"string"

我只是想试一试这个。

这是一个行:

awk -v strVar='"string"' -v count=-1 '
NR>1 { $0 ~ strVar && ++count && gsub(strVar, strVar count) }
1' file1 file2 file3 file4

您基本上:

  1. 初始化计数器,(-v count=-1
  2. (
  3. 忽略第一个输入行 (NR>1(
  4. 检查行是否与字符串匹配 ($0 ~ strVar(
  5. 如果它确实增加了计数器(&& ++count(
  6. 如果增加的计数器大于零(++count将返回0 -> false值为零并从此>0 -> true,因此它也根据需要作为打印条件工作(
    • 开始用递增的后缀替换字符串 (&& gsub(str, str count)
  7. 打印结果 ({}1(

请注意,如果您不介意也计算第一行,和/或知道file1的第一行不包含"字符串">,那么解决方案可以更小/更简单:

awk -v strVar='"string"' -v count=1 '
{ gsub(strVar, strVar count) && count++ }
1' file1 file2 file3 file4

这意味着对于每个替换,您都会增加计数器,并将输出:

% awk -v strVar='"string"' -v count=1 '{ gsub(strVar, strVar count) && count++ }1' file1 file2 file3 file4
some text
"string"1 here
some text
"string"2 here
some more
text "string"3
why "string"4
some text
why here
some more
text pttn
why pttn
some "string"5
no here

问候

最新更新