更快的解决scheme来比较bash中的文件

更快的解决scheme来比较bash中的文件,第1张

概述更快的解决scheme来比较bash中的文件

文件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中的文件所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1274595.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存