awk加入脚本让我绝对笨拙

时间:2016-02-07 06:11:28

标签: awk

我尝试使用awk从第一个CSV文件“map.txt”中查找带有两列(col1 = key,col2 = value)的值,然后使用第二个文件“textile.txt”的第3列当用文件1的col2替换相同的col3时作为键。

示例文件:

的map.txt

a,apple
b,pear
c,peeps
d,gingersnaps
e,goop

TextFile.txt的

1,This is one,a
2,This is two,b
3,This is three,c
4,This is four,d
5,This is five,e

所需的输出:

1,This is one,apple
2,This is two,pear
3,This is three,peeps
4,This is four,gingersnaps
5,This is five,goop

结果: 我已经使用测试文件进行了这项工作,但是当使用实际文件时,虽然键被正确读入数组,但只有一行,如果存在多行,则最后一行实际上是正确替换的。< / p>

已尝试各种版本的awk脚本 - 当前版本详细且使用getline进行调试:

#!/usr/bin/awk -f

BEGIN{FS=OFS=","}

(FNR==NR){
fname=ARGV[ARGC-2];
print fname;
do
{getline < fname;
lookup[$1]=$2;
print $1 " = " $2;
}
while (getline);
close(fname)
fname=ARGV[ARGC-1];
}

(fname==ARGV[ARGC-1]){
print fname;
do
{getline < ARGV[ARGC-1];
$3=lookup[$3];
print $3 " " $0;
}
while (getline);
next;
} 

对于它的价值,这是在OSX上。

2 个答案:

答案 0 :(得分:4)

我认为你太复杂了。 这似乎有效:

#!/usr/bin/awk -f

BEGIN {
    FS=OFS=","
}

NR == FNR {
    lookup[$1] = $2
}

NR != FNR {
    print $1,$2,lookup[$3]
}

运行这个,我得到:

# ./thing.awk map.txt textfile.txt
1,This is one,apple
2,This is two,pear
3,This is three,peeps
4,This is four,gingersnaps
5,This is five,goop

第一个块NR == FNR { .. }读取地图文件。第二个读取textfile.txt(以及您在命令行中放置的任何其他文件)。

答案 1 :(得分:0)

以下脚本避免了(可能很小的)必须测试NR == FNR的开销,并且可以很容易地指定要翻译的字段的列号(这里:col = 3):

awk -F, -v col=3 -v dict=map.txt '
  BEGIN {OFS=FS; while( (getline<dict) > 0) {a[$1]=$2} }
  a[$col] {$col = a[$col]}
  { print $0 }
' textfile.txt

请注意,如果&#39;键&#39;在字典中找不到数据文件中的一行(textfile.txt),然后上面的脚本将打印该行而不进行更改。如果这不是所需的行为,则可以轻松调整脚本。