文件1:
chr1 14361 14829 NR_024540_0_r_DDX11L1,WASH7P_468 chr1 14969 15038 NR_024540_1_r_WASH7P_69 chr1 15795 15947 NR_024540_2_r_WASH7P_152 chr1 16606 16765 NR_024540_3_r_WASH7P_15 chr1 16857 17055 NR_024540_4_r_WASH7P_198
和file2:
NR_024540 11
我需要在file1find匹配file2并打印整个file1 + second column of file2
所以ouptut是:
按小时计数
如何使用AWK从string中删除所有小写字符?
使用awk删除字节顺序标记
外推 – 基于awk
在bash中parsingCSV并分配variables
chr1 14361 14829 NR_024540_0_r_DDX11L1,WASH7P_468 11 chr1 14969 15038 NR_024540_1_r_WASH7P_69 11 chr1 15795 15947 NR_024540_2_r_WASH7P_152 11 chr1 16606 16765 NR_024540_3_r_WASH7P_15 11 chr1 16857 17055 NR_024540_4_r_WASH7P_198 11
我的解决scheme在bash中非常慢:
#!/bin/bash while read line; do c=$(echo $line | awk '{print $1}') d=$(echo $line | awk '{print $2}') grep $c file1 | awk -v line="$d" -v OFS="t" '{print $1,$2,$3,$4"_"line}' >> output done < file2
我更喜欢更快的任何bash或awk解决scheme。 输出可以被修改,但需要保留所有的信息(列的顺序可以不同)。
编辑:
现在它看起来像根据@chepner最快的解决scheme:
#!/bin/bash while read -rcd; do grep $c file1 | awk -v line="$d" -v OFS="t" '{print $1,$4"_"line}' done < file2 > output
awk,pipe道和尾巴-f给予意想不到的行为
Unix shell查找最大值和最小值并从文件中打印行
在每个换行符之间删除文件中的换行符
如何比较bash中的两个范围列表?
search文件中最后一个string的发生并追加到它
另一个解决方法是使用join和sed ,假设file1和file2是排序的
join <(sed -r 's/[^ _]+_[^_]+/& &/' file1) file2 -1 4 -2 1 -o "1.1 1.2 1.3 1.5 2.2" > output
如果输出顺序不重要,可以使用awk
awk 'FNR==NR{d[$1]=$2; next} {split($4,v,"_"); key=v[1]"_"v[2]; if(key in d) print $0,d[key]} ' file2 file1
你得到,
chr1 14361 14829 NR_024540_0_r_DDX11L1,WASH7P_468 11
chr1 14969 15038 NR_024540_1_r_WASH7P_69 11
chr1 15795 15947 NR_024540_2_r_WASH7P_152 11
chr1 16606 16765 NR_024540_3_r_WASH7P_15 11
chr1 16857 17055 NR_024540_4_r_WASH7P_198 11
在一个Awk命令中,
awk 'FNR==NR{map[$1]=$2; next}{ for (i in map) if($0 ~ i){$(NF+1)=map[i]; print; next}}' file2 file1 chr1 14361 14829 NR_024540_0_r_DDX11L1,WASH7P_468 11 chr1 14969 15038 NR_024540_1_r_WASH7P_69 11 chr1 15795 15947 NR_024540_2_r_WASH7P_152 11 chr1 16606 16765 NR_024540_3_r_WASH7P_15 11 chr1 16857 17055 NR_024540_4_r_WASH7P_198 11
多线程中更可读的版本
FNR==NR { # map the values from 'file2' into the hash-map 'map' map[$1]=$2 next } # On 'file1' do { # Iterate through the array map for (i in map){ # If there is a direct regex match on the line with the # element from the hash-map,print it and append the # hash-mapped value at last if($0 ~ i){ $(NF+1)=map[i] print next } } }
尝试这个 –
cat file2 NR_024540 11 NR_024541 12 cat file11 chr1 14361 14829 NR_024540_0_r_DDX11L1,WASH7P_468 chr1 14361 14829 NR_024542_0_r_DDX11L1,WASH7P_468 chr1 14969 15038 NR_024540_1_r_WASH7P_69 chr1 15795 15947 NR_024540_2_r_WASH7P_152 chr1 16606 16765 NR_024540_3_r_WASH7P_15 chr1 16857 17055 NR_024540_4_r_WASH7P_198 chr1 14361 14829 NR_024540_0_r_DDX11L1,WASH7P_468 chr1 14969 15038 NR_024540_1_r_WASH7P_69 chr1 15795 15947 NR_024540_2_r_WASH7P_152 chr1 16606 16765 NR_024540_3_r_WASH7P_15 awk 'NR==FNR{a[$1]=$2;next} substr($4,1,9) in a {print $0,a[substr($4,9)]}' file2 file11 chr1 14361 14829 NR_024540_0_r_DDX11L1,WASH7P_468 11 chr1 14969 15038 NR_024540_1_r_WASH7P_69 11 chr1 15795 15947 NR_024540_2_r_WASH7P_152 11 chr1 16606 16765 NR_024540_3_r_WASH7P_15 11 chr1 16857 17055 NR_024540_4_r_WASH7P_198 11 chr1 14361 14829 NR_024540_0_r_DDX11L1,WASH7P_468 11 chr1 14969 15038 NR_024540_1_r_WASH7P_69 11 chr1 15795 15947 NR_024540_2_r_WASH7P_152 11 chr1 16606 16765 NR_024540_3_r_WASH7P_15 11
性能 – (测试55000条记录)
time awk 'NR==FNR{a[$1]=$2;next} substr($4,9)]}' file2 file1 > output1 real 0m0.16s user 0m0.14s sys 0m0.01s
您不必要地启动了大量的外部程序。 让read从文件2拆分入线,而不是两次调用awk 。 也没有必要运行grep ; awk可以做自己的过滤。
while read -rcd; do awk -v fIEld="$c" -v line="$d" -v OFS='t' '$0 ~ fIEld {print $1,$4"_"line}' file1 done < file2 > output
如果搜索到的字符串总是相同的长度( length("NR_024540")==9 ):
awk 'NR==FNR{a[$1]=$2;next} (i=substr($4,9)) && (i in a){print $0,a[i]}' file2 file1
解释:
NR==FNR { # process file2 a[$1]=$2 # hash record using $1 as the key next # skip to next record } (i=substr($4,9)) && (i in a) { # read the first 9 bytes of $4 to i and search in a print $0,a[i] # output if found }
awk -F '[[:blank:]_]+' ' FNR==NR { a[$2]=$3 ;next } { if ( $5 in a ) $0 = $0 " " a[$5] } 7 ' file2 file1
评论:
使用_作为额外的字段分隔符,所以文件名比较容易在两个文件中进行比较(只使用数字部分)。
7是为了好玩,它只是一个非0值 – >打印行
我不改变字段(NF + 1,…),所以我们保持原来的格式只加入参考号码
一个较小的oneliner代码(针对代码大小进行了优化)(假定file1中的非空行是必需的)。 如果分隔符只有空格,则可以用空格字符替换[:blank:]
awk -F '[[:blank:]_]+' 'NF==3{a[$2]=$3;next}$0=$0" "a[$5]' file2 file1
没有awk或sed需要。 这假定file2只有一行:
n="`cut -f 2 file2`" ; while read x ; do echo "$x $n" ; done < file1
总结以上是内存溢出为你收集整理的更快的解决scheme来比较bash中的文件全部内容,希望文章能够帮你解决更快的解决scheme来比较bash中的文件所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)