我正在尝试编写一个将两个文件作为输入的脚本:
1)带注释的制表符分隔文件(" inFile")和
2)一个可变长度的文件,包含其他带注释的制表符分隔文件(相同的格式),每个文件用set_ids进行搜索...
file1 set1
file2 set2
file3 set3
我想输出inFile,但是附加了一些列,表明在每个要搜索的集合中是否找到了每行file_A。
这是我目前的代码
#!/bin/bash
inFile=$1
inSets=$2
set_filter () {
set_name=$3
awk -F"\t" ' BEGIN {OFS="\t"};
{
FNR == NR
{
idx=($1"."$2"."$3)
keys[$idx]=$set_name
next
}
{
idx=($1"."$2"."$3)
print $0, keys[$idx]
}
} ' $2 $1
}
IFS=$'\n'
for line in $(cat $inSets); do
set_file=$(echo $line | cut -f 1)
set_id=$(echo $line | cut -f 2)
??? set_filter $inFile $set_file $set_id
done
我的基本想法是定义一个函数,该函数将执行单个文件的查找,并在循环中使用它来搜索所有要搜索的文件,并在每次迭代时添加一列。然而,我在循环方面遇到了麻烦,希望有人能指出我正确的方向。谢谢!
修改
带注释的文件看起来像
# inFile:
day start stop
1 100 102
1 300 350
2 100 200
3 200 400
所以我正在寻找实例(行),其中同一天.start.stop出现在被搜索的其中一个集合中。如果set1是:
day start stop
1 100 102
1 700 750
2 800 900
3 900 950
和set 2是:
day start stop
3 200 400
1 100 102
2 800 880
1 300 350
然后输出应该如下:
day start stop
1 100 102 set1 set2
1 300 350 set2
2 100 200
3 200 400 set2
答案 0 :(得分:1)
以下是使用awk
的一种方式:
awk '
FILENAME != "infile" {
line[FILENAME,$0] = FILENAME
next
}
FNR > 1 {
printf "%s", $0
for (x in line) {
split (x, t, SUBSEP)
if (t[2] == $0) {
sep = FS
printf "%s%s", sep, line[x]
}
}
print "";
next
}1' set1 set2 infile
day start stop
1 100 102 set2 set1
1 300 350 set2
2 100 200
3 200 400 set2
您可以继续添加套装,以确保您的infile在最后。
答案 1 :(得分:0)
这是另一个全部的答案。创建以下可执行awk文件:
#!/usr/bin/awk -f
BEGIN {DELIM=","; OFS="\t"} # DELIM should just be different than FS/data
# reformat input, set up some arrays
NR==FNR {
line = $1 OFS $2 OFS $3 # replace with $0 if first file is tab delimited
if(FNR==1) header=line
else { a[$2$3]=line; order[FNR-1]=$2$3; cnt++ }
next
}
FILENAME!=last_filename { f[FILENAME]=++fcnt; last_filename=FILENAME }
$2$3 in a { a[$2$3]=a[$2$3] DELIM FILENAME }
# loop over lines in input file, adjusting formatting of lines in a[] with f[]
END {
print header
for(i=1;i<=cnt;i++) {
split(a[order[i]], oarr, DELIM)
printf( "%s", oarr[1] )
k=2
for(j=1;j<=fcnt;j++) {
fname=oarr[k]
if( f[fname]==j ) {o=fname; k++}
else o=""
printf( "%s%s", OFS, o )
}
print ""
}
}
当放入名为awko
的文件时,它可以像awko infile set*
:
day start stop
1 100 102 set1 set2
1 300 350 set2
2 100 200
3 200 400 set2
一般细分:
a[]
a[]
中的每一行,重新格式化以匹配匹配存在line
变量,因为问题中的数据在翻译中丢失了标签。