替换文件中的列,但保留空格格式



我下面有一个代码,它根据文件B中的数据替换了文件A中的第4列,但输出没有保留原始文件的空格。有什么办法吗?

 tr , " " <fileB | awk 'NR==FNR{a[$2]=$1;next} {$4=a[$4];print}' - fileA

文件A

 xxx    xxx   xxx Z0002

文件B

 3100,3000
 W0002,Z0002

使用上面的代码输出:

 xxx xxx xxx W0002

预期输出:

xxx    xxx   xxx W0002

这应该可以:

awk 'FNR==NR {split($0,a,",");b[a[2]]=a[1];next} {n=split($0,d,/[^[:space:]]*/);if(b[$4])$4=b[$4];for(i=1;i<=n;i++) printf("%s%s",d[i],$i);print ""}' fileB fileA

它将空格存储在数组中,以便以后可以重用它

例:

cat fileA
xxx    xxx   xxx Z0002   not change this
xxx   xxx  Z0002 zzz
xxx Z000223213 xxx Z0002 xxx xxx xxx Z0002

cat fileB
3100,3000
W0002,Z0002

awk 'FNR==NR {split($0,a,",");b[a[2]]=a[1];next} {n=split($0,d,/[^[:space:]]*/);if(b[$4])$4=b[$4];for(i=1;i<=n;i++) printf("%s%s",d[i],$i);print ""}' fileB fileA
xxx    xxx   xxx  W0002   not change this
xxx   xxx  Z0002 zzz
xxx Z000223213 xxx  W0002 xxx xxx xxx Z0002


一些更具可读性及其工作原理:

awk '
FNR==NR {                           # For the first file "fileB"
    split($0,a,",")                 # Split it to an array "a" using "," as separator 
    b[a[2]]=a[1]                    # Store the data in array "b" using second column as index
    next                            # Skip to next record
    }
    {                               # Then for the file "fileA"
    n=split($0,d,/[^[:space:]]*/)   # Split the spaces inn group and store them in array "d"
    if(b[$4])                       # If array "b" as data for field "4"
        $4=b[$4]                    # Change filed "4" to data found in array "b"
    for(i=1;i<=n;i++)               # Loop trough all field in the line
        printf("%s%s",d[i],$i)      # print correct separator and data
    print ""                        # Add new line at the end
    }
' fileB fileA                       # Read the files.

使用 gsub(正则表达式替换),在它之前有空格模式,在它之后$行结束就可以解决问题。

测试文件:

$ cat fileA
xxx    xxx   xxx Z0002
xxx    xxx   Z0002 xxx
xxx    xxx   xxx Z0002YY

命令执行和结果:

$ tr , " " <fileB | awk 'NR==FNR{a[$2]=$1;next}  a[$4]=="" {print} a[$4]!=""{gsub(" "$4"$", " "a[$4], $0);print}' - fileA
xxx    xxx   xxx W0002
xxx    xxx   Z0002 xxx
xxx    xxx   xxx Z0002YY

冗长的尴尬答案

对于这个问题来说,这有点矫枉过正,但我认为这对其他人很有用。

它将避免元字符和行上其他地方出现的模式问题。

awk 'FNR==NR {split($0,a,",");b[a[2]]=a[1];next}
     {
         while(match(substr($0,x+=(RSTART+RLENGTH-(x>1?1:0))),"[^[:space:]]+")){
             E[++D]=(RSTART+x-(x>1?1:0))
             F[D]=E[D]+RLENGTH
         }
     }
     b[$4]~/./{$0=substr($0,0,E[4]-1) b[$4] substr($0,F[4])}
     {x=1;D=0;delete E}1' FILEB FILEA
<小时 />

输入

菲拉

xxx    Z0002   xxx Z0002 xxx    xxx   xxx Z0002
xxx    Z0002   xxx dsasa xxx    xxx   xxx Z0002

菲勒布

3100,3000
W0002,Z0002

输出

xxx    Z0002   xxx W0002 xxx    xxx   xxx Z0002
xxx    Z0002   xxx dsasa xxx    xxx   xxx Z0002
<小时 />

解释

稍后会添加

最新更新