Awk 替换相同范围内的数字

Awk 替换相同范围内的数字,awk,sed,Awk,Sed,我有一个tab delim file1,其中第一列如下所示 1 1 6 6 6 1A 1A 1B 2 2 2 2 3 4 4A Z Z 我想替换为1=1,1A=2,1B=3,2=4,3=5,4=6,4A=7,6=8,Z=9 然后输出应该是 1 1 8 8 8 2 2 3 4 4 4 4 5 6 7 9 9 我在其他帖子中说过,为了避免累积替换,我应该从较大的值到较小的值,并使用以下方法进行多次替换: sed -e 's/a/b/g ; s/b/d/g' file 但我有60个替补 有没有一

我有一个tab delim file1,其中第一列如下所示

1
1
6
6
6
1A
1A
1B
2
2
2
2
3
4
4A
Z
Z
我想替换为
1=1,1A=2,1B=3,2=4,3=5,4=6,4A=7,6=8,Z=9
然后输出应该是

1
1
8
8
8
2
2
3
4
4
4
4
5
6
7
9
9
我在其他帖子中说过,为了避免累积替换,我应该从较大的值到较小的值,并使用以下方法进行多次替换:

sed -e 's/a/b/g ; s/b/d/g' file
但我有60个替补

有没有一种方法可以在循环中或其他替代方法中执行此操作,而不是编写60个替换


请注意,每个元素重复不同的时间,它们可以是数字和字符,但我将它们全部替换为数字1-60,并以预定义的顺序,而不是它们显示的顺序。“我的文件”的其他列具有相同的字符,但我只想替换第1列中的内容。

使用搜索和替换字符串创建一个映射文件,如下所示:

cat mapping
1   1
1A  2
1B  3
2   4
3   5
4   6
4A  7
6   8
Z   9
然后只需使用此
awk
即可在单个命令中获得所有替换:

awk 'BEGIN{FS=OFS="\t"} NR == FNR{key[$1]=$2; next} $1 in key{$1=key[$1]} 1' mapping file


请您尝试以下操作(在
BEGIN
部分中添加额外的
FS=OFS=“\t”
,以防您有制表符分隔的输入文件,并且您也需要制表符形式的输出)

awk'
开始{
key=“1,1A,1B,2,3,4,4A,6,Z”
value=“1,2,3,4,5,6,7,8,9”
拆分(键,数组1,“,”)
num=拆分(值,数组2,“,”)

对于(i=1;i单个数字前缀,这将在无需手动映射的情况下工作

$ awk 'NR==FNR {a[$1]; next} 
       FNR==1  {asorti(a,b); for(k in b) c[b[k]]=k} 
               {print c[$1]}' file{,}

1
1
8
8
8
2
2
3
4
4
4
4
5
6
7
9
9
请注意,6映射到8,而不是样本输出中的4。

这可能适用于您(GNU-sed):

将查找表追加到每行,并使用模式匹配和反向引用将第一列转换为所需字符串


注意:没有匹配查找的行不会被更改。

因为您只想使用从1开始的连续数字作为替换,所以您只需要:

awk '
BEGIN {
    split("1 1A 1B 2 3 4 4A 6 Z",tmp)
    for (i in tmp) {
        map[tmp[i]] = i
    }
    FS = OFS = "\t"
}
$1 in map { $1 = map[$1] }
1' file
1
1
8
8
8
2
2
3
4
4
4
4
5
6
7
9
9
1

不管最终使用什么解决方案,你都必须在新旧值之间创建一个映射,所以我只需要写60个替换,然后就可以了。好吧!那最好开始吧。Thxs你的描述
1=1,1A=2,1B=3,2=4,3=5,4=6,4A=7,6=8,Z=9没有解释
6
是如何实现的>在输入中,输入变成输出中的
4
。请确保您的描述与示例相符,并确保示例中包含可能在翻译顺序错误时出错的情况。拼写错误已修复。注意Thxs。
$ awk 'NR==FNR {a[$1]; next} 
       FNR==1  {asorti(a,b); for(k in b) c[b[k]]=k} 
               {print c[$1]}' file{,}

1
1
8
8
8
2
2
3
4
4
4
4
5
6
7
9
9
sed -E 's/$/\n:1=1:1A=2:1B=3:2=4:3=5:4=6:4A=7:6=8:Z=9/;s/^(\S+)(.*)\n.*:\1=([^:]*).*/\3\2/;P;d' file
awk '
BEGIN {
    split("1 1A 1B 2 3 4 4A 6 Z",tmp)
    for (i in tmp) {
        map[tmp[i]] = i
    }
    FS = OFS = "\t"
}
$1 in map { $1 = map[$1] }
1' file
1
1
8
8
8
2
2
3
4
4
4
4
5
6
7
9
9
1