如何用 BASH 中的递增数字替换所有匹配项?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23577516/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 10:25:14  来源:igfitidea点击:

How to replace all matches with an incrementing number in BASH?

bashsed

提问by Village

I have a text file like this:

我有一个这样的文本文件:

AAAAAA this is some content.
This is AAAAAA some more content AAAAAA. AAAAAA
This is yet AAAAAA some more [AAAAAA] content.

I need to replace all occurrence of AAAAAAwith an incremented number, e.g., the output would look like this:

我需要AAAAAA用递增的数字替换所有出现的,例如,输出将如下所示:

1 this is some content.
This is 2 some more content 3. 4
This is yet 5 some more [6] content.

How can I replace all of the matches with an incrementing number?

如何用递增的数字替换所有匹配项?

回答by jaypal singh

Here is one way of doing it:

这是一种方法:

$ awk '{for(x=1;x<=NF;x++)if($x~/AAAAAA/){sub(/AAAAAA/,++i)}}1' file
1 this is some content.
This is 2 some more content 3. 4
This is yet 5 some more [6] content.

回答by rici

A perl solution:

一个 perl 解决方案:

perl -pe 'BEGIN{$A=1;} s/AAAAAA/$A++/ge' test.dat

回答by potong

This might work for you (GNU sed):

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

sed -r ':a;/AAAAAA/{x;:b;s/9(_*)$/_/;tb;s/^(_*)$/0/;s/$/:0123456789/;s/([^_])(_*):.*(.).*//;s/_/0/g;x;G;s/AAAAAA(.*)\n(.*)//;ta}' file

This is a toy example, perl or awk would be a better fit for a solution.

这是一个玩具示例,perl 或 awk 更适合解决方案。

The solution only acts on lines which contain the required string (AAAAAA).

该解决方案仅作用于包含所需字符串 ( AAAAAA) 的行。

The hold buffer is used as a place to keep the incremented integer.

保持缓冲区用作保存递增整数的地方。

In overview: when a required string is encountered, the integer in the hold space is incremented, appended to the current line, swapped for the required string and the process is then repeated until all occurences of the string are accounted for.

概述:当遇到所需的字符串时,保持空间中的整数递增,附加到当前行,交换所需的字符串,然后重复该过程,直到字符串的所有出现都被考虑在内。

Incrementing an integer simply swaps the last digit (other than trailing 9's) for the next integer in sequence i.e. 0 to 1, 1 to 2 ... 8 to 9. Where trailing 9's occur, each trailing 9 is replaced by a non-integer character e.g '_'. If the number being incremented consists entirely of trailing 9's a 0is added to the front of the number so that it can be incremented to 1. Following the increment operation, the trailing 9's (now _'s) are replaced by '0's.

递增整数只是将最后一位数字(除了尾随 9 之外)按顺序交换下一个整数,即 0 到 1、1 到 2 ... 8 到 9。在尾随 9 出现的情况下,每个尾随 9 被非整数替换字符,例如“_”。如果被递增的数字完全由尾随的 9 组成0,则将a添加到数字的前面,以便它可以递增到1。在增量操作之后,尾随的 9(现在是_'s)被 '0' 替换。

As an example say the integer 9 is to be incremented:

例如,要增加整数 9:

9is replaced by _, a 0is prepended (0_), the 0is swapped for 1 (1_), the _is replaced by 0. resulting in the number 10.

9被替换为_,a0被前置 ( 0_),0被替换为 1 ( 1_),_被替换为0。导致数10

See comments directed at @jaypal for further notes.

有关更多说明,请参阅针对@jaypal 的评论。

回答by sachin

Perl did the job for me

Perl 为我完成了这项工作

perl -pi -e 's/\b'DROP'\b/$&.'_'.++$A /ge' /folder/subfolder/subsubfolder/*

Input:

输入:

DROP
drop
$drop
$DROP
$DROP="DROP"
$DROP='DROP'
$DROP=$DROP
$DROP="DROP";
$DROP='DROP';
$DROP=$DROP;
$var="DROP_ACTION"
drops
DROPS
CODROP
'DROP'
"DROP"
/DROP/

Output:

输出:

DROP_1
drop
$drop
$DROP_2
$DROP_3="DROP_4"
$DROP_5='DROP_6'
$DROP_7=$DROP_8
$DROP_9="DROP_10";
$DROP_11='DROP_12';
$DROP_13=$DROP_14;
$var="DROP_ACTION"
drops
DROPS
CODROP
'DROP_15'
"DROP_16"
/DROP_17/

回答by baliman

Maybe something like this

也许像这样

#!/bin/bash
NR=1
cat filename  while read line
do
   line=$(echo $line | sed 's/AAAAA/$NR/')
   echo ${line}
   NR=$((NR + 1 ))
done