[英]Shell script - join two files using the AWK on specific column
I have first file test1.csv separated with pipes and one tab always: 我有第一个文件test1.csv用管道和一个标签分开:
ug|s|B|city|bg1|1|8D|ON-05|100 10|28|288
ug|s|B|city|bg1|1|D9|ON-05|150 11|28|288
ug|s|B|city|bg2|2|94|ON-05|350 12|28|288
I have second file test2.csv only with one tab: 我有第二个文件test2.csv只有一个选项卡:
bg1 250
bg2 350
I want to join them using the column number 5 from the first file (bg1,bg2) so I can take the values from second file (250,350) 我想使用第一个文件(bg1,bg2)中的第5列连接它们,所以我可以从第二个文件中获取值(250,350)
So the final output should be: 所以最终的输出应该是:
ug|s|B|city|bg1|1|8D|ON-05|100|250 10|28|288
ug|s|B|city|bg1|1|D9|ON-05|150|250 11|28|288
ug|s|B|city|bg2|2|94|ON-05|350|350 12|28|288
I tried using the AWK to join them: 我尝试使用AWK加入它们:
awk -F '|' -v OFS='|' '
FNR==NR { } {
split($NF, b, "\t")
$NF = b[1] FS a[b[1]] "\t" b[2]
} 1' test2.csv test1.csv > final.csv
but not getting correct results 但没有得到正确的结果
awk '
BEGIN { FS=OFS="\t"; subFs="|" }
NR==FNR { map[$1]=$2; next }
{ split($1,subFlds,subFs); print $1 subFs map[subFlds[5]], $2 }
' test2.csv test1.csv
ug|s|B|city|bg1|1|8D|ON-05|100|250 10|28|288
ug|s|B|city|bg1|1|D9|ON-05|150|250 11|28|288
ug|s|B|city|bg2|2|94|ON-05|350|350 12|28|288
This is the perfect use case for my general proposition that -v
should be avoided in favor of direct assignment on the command line. 对于我的一般命题,这是一个完美的用例,应该避免使用
-v
以支持在命令行上直接赋值。 You can easily switch FS between files and do: 您可以轻松地在文件之间切换FS并执行:
$ awk 'NR==FNR{f[$1]=$2; next} {print $0, f[$5]}' test2.csv FS=\| OFS=\| test1.csv
ug|s|B|city|bg1|1|8D|ON-05|100 10|28|288|250
ug|s|B|city|bg1|1|D9|ON-05|150 11|28|288|250
ug|s|B|city|bg2|2|94|ON-05|350 12|28|288|350
This doesn't give you exactly the output you desire, but that's easy enough to fix, albeit a little awkward: 这并没有给你你想要的输出,但这很容易修复,虽然有点尴尬:
awk 'NR==FNR{f[$1]=$2; next} {split($9,a,"\t"); \
$9=a[1] "|" f[$5] "\t" a[2]}1' test2.csv FS=\| OFS=\| test1.csv
You can do this with Perl also. 您也可以使用Perl执行此操作。
$ cat test2.csv
bg1 250
bg2 350
$ cat test1.csv
ug|s|B|city|bg1|1|8D|ON-05|100 10|28|288
ug|s|B|city|bg1|1|D9|ON-05|150 11|28|288
ug|s|B|city|bg2|2|94|ON-05|350 12|28|288
$ perl -F'\t' -lane 'if($ARGV eq "test2.csv") { $kv{$F[0]}=$F[1]}; if( $ARGV eq "test1.csv" ) { ($x,$y)=(split(/\|/,$F[0]))[4,8]; if($kv{$x}) {$F[0]=~s/$y$/$kv{$x}/g } pr
int "$F[0]\t$F[1]" } ' test2.csv test1.csv
ug|s|B|city|bg1|1|8D|ON-05|250 10|28|288
ug|s|B|city|bg1|1|D9|ON-05|250 11|28|288
ug|s|B|city|bg2|2|94|ON-05|350 12|28|288
$
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.