如何在unix中使用awk with tr命令转换文件中的列值


How to translate a column value in the file using awk with tr command in unix

细节:

输入文件:file.txt

1
2
3
P123456789,COLUMN2
P123456790,COLUMN2
P123456791,COLUMN2

预期产量:

1
2
3
Z678999999,COLUMN2
Z678999995,COLUMN2
Z678999996,COLUMN2

如果我尝试使用变量,它会给出正确的结果。

1
2
(i.e) /tmp>echo"P123456789"|tr"0-9""5-9"|tr"A-Z""X-Z"
Z678999999

但是,如果我使用awk命令,它不会给出结果而是给出错误:

1
2
3
4
5
6
7
/tmp>$ awk 'BEGIN { FS=OFS="," } { $1=echo $1|tr"0-9""5-9"|tr"A-Z""X-Z";$2="COLUMN2"); print }' /tmp/file.txt >/tmp/file.txt.tmp
awk: BEGIN { FS=OFS="," } { $1=echo $1|tr"0-9""5-9"|tr"A-Z""X-Z";$2="COLUMN2"); print }
awk:                                   ^ syntax error
awk: BEGIN { FS=OFS="," } { $1=echo $1|tr"0-9""5-9"|tr"A-Z""X-Z";$2="COLUMN2"); print }
awk:                                                  ^ syntax error
awk: BEGIN { FS=OFS="," } { $1=echo $1|tr"0-9""5-9"|tr"A-Z""X-Z";$2="COLUMN2"); print }
awk:                                                                             ^ syntax error

有人可以帮忙吗?


只是做你想做的事,而不改变你的逻辑:

awk行:

1
awk -F, -v OFS="," '{"echo ""$1""|tr "0-9" "5-9"|tr "A-Z" "X-Z"" |getline $1}7'

与您的数据:

1
2
3
4
5
6
kent$  echo"P123456789,COLUMN2
P123456790,COLUMN2
P123456791,COLUMN2"|awk -F, -v OFS="," '{"echo ""$1""|tr "0-9" "5-9"|tr "A-Z" "X-Z"" |getline $1}7'                                                              
Z678999999,COLUMN2
Z678999995,COLUMN2
Z678999996,COLUMN2


不幸的是,AWK没有内置的翻译功能。 你可以像Ed Morton那样编写一个,但我会伸手去拿(并强烈推荐)一个更强大的工具。 例如,Perl可以使用autosplit(-a)命令开关处理字段:

-a turns on autosplit mode when used with a -n or -p. An implicit split command to the @F array is done as the first thing inside the
implicit while loop produced by the -n or -p.

您可以输入perldoc perlrun以获取更多详细信息。

这是我的解决方案:

1
perl -F, -lane '$F[0] =~ tr/0-9/5-9/; $F[0] =~ tr/A-Z/X-Z/; print join (",", @F)' file.txt

结果:

1
2
3
Z678999999,COLUMN2
Z678999995,COLUMN2
Z678999996,COLUMN2


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ cat tst.awk
function tr(old,new,str,        oldA,newA,strA,i,j) {
    split(old,oldA,"")
    split(new,newA,"")
    split(str,strA,"")
    str =""
    for (i=1;i in strA;i++) {
        for (j=1;(j in oldA) && !sub(oldA[j],newA[j],strA[i]);j++)
            ;
        str = str strA[i]
    }
    return str
}

BEGIN { FS=OFS="," }
{ print tr("P012345678","Z567899999",$1), $2 }

$ awk -f tst.awk file
Z678999999,COLUMN2
Z678999995,COLUMN2
Z678999996,COLUMN2