下面的代码根据文件 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.
关于bash - 替换文件中的列但保持空格格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29915607/