Bash zgrep不会像grep那样停止脚本

Bash zgrep不会像grep那样停止脚本,bash,ubuntu,unix,Bash,Ubuntu,Unix,我是Bash脚本的新手,我正在尝试让这个脚本逐行读取文件a.txt.gz,并检查该行的第二个值是否也存在于b.txt.gz文件中 我不知道为什么zgrep在读了a.txt.gz之后不会结束脚本,它卡在了闪烁的指针上 下面是代码测试 zcat /home/tdq/Bash/a.txt.gz | while read p0 p1 do if zgrep -q -e "[A-Za-z0-9=;._|()\t]*${p1}[A-Za-z0-9=;._|()\t]*" /home/tdq/Bash/b.t

我是Bash脚本的新手,我正在尝试让这个脚本逐行读取文件a.txt.gz,并检查该行的第二个值是否也存在于b.txt.gz文件中

我不知道为什么zgrep在读了a.txt.gz之后不会结束脚本,它卡在了闪烁的指针上

下面是代码测试

zcat /home/tdq/Bash/a.txt.gz | while read p0 p1
do
if zgrep -q -e "[A-Za-z0-9=;._|()\t]*${p1}[A-Za-z0-9=;._|()\t]*" /home/tdq/Bash/b.txt.gz; then
    echo "FOUND"
fi
当我运行time./test时的结果与我预期的一样,但是脚本不会结束,下面是输出

FOUND
FOUND
FOUND
我试着使用grep,没有找到,但它可以结束脚本

zcat /home/tdq/Bash/a.txt.gz | while read p0 p1
do
    if grep -q -e "[A-Za-z0-9=;._|()\t]*${p1}[A-Za-z0-9=;._|()\t]*" /home/tdq/Bash/b.txt.gz; then
        echo "FOUND"
    fi
done
运行时的结果。/test

有人能帮我吗,非常感谢

a、 txt.gz选项卡分离

1   rs367896724
2   rs540431307
3   rs555500075
4   rs548419688
1   10177   rs367896724 A   AC  100 PASS    AC=2130;AF=0.425319;AN=5008;NS=2504;DP=103152;EAS_AF=0.3363;AMR_AF=0.3602;AFR_AF=0.4909;EUR_AF=0.4056;SAS_AF=0.4949;AA=|||unknown(NO_COVERAGE);VT=INDEL GT  1|0 0|1 0|1
2   10177   rs540431307 A   AC  100 PASS    AC=2130;AF=0.425319;AN=5008;NS=2504;DP=103152;EAS_AF=0.3363;AMR_AF=0.3602;AFR_AF=0.4909;EUR_AF=0.4056;SAS_AF=0.4949;AA=|||unknown(NO_COVERAGE);VT=INDEL GT  1|0 0|1 0|1
3   10177   rs555500075 A   AC  100 PASS    AC=2130;AF=0.425319;AN=5008;NS=2504;DP=103152;EAS_AF=0.3363;AMR_AF=0.3602;AFR_AF=0.4909;EUR_AF=0.4056;SAS_AF=0.4949;AA=|||unknown(NO_COVERAGE);VT=INDEL GT  1|0 0|1 0|1
4   10177   rs548419688 A   AC  100 PASS    AC=2130;AF=0.425319;AN=5008;NS=2504;DP=103152;EAS_AF=0.3363;AMR_AF=0.3602;AFR_AF=0.4909;EUR_AF=0.4056;SAS_AF=0.4949;AA=|||unknown(NO_COVERAGE);VT=INDEL GT  1|0 0|1 0|1
b、 txt.gz选项卡分离

1   rs367896724
2   rs540431307
3   rs555500075
4   rs548419688
1   10177   rs367896724 A   AC  100 PASS    AC=2130;AF=0.425319;AN=5008;NS=2504;DP=103152;EAS_AF=0.3363;AMR_AF=0.3602;AFR_AF=0.4909;EUR_AF=0.4056;SAS_AF=0.4949;AA=|||unknown(NO_COVERAGE);VT=INDEL GT  1|0 0|1 0|1
2   10177   rs540431307 A   AC  100 PASS    AC=2130;AF=0.425319;AN=5008;NS=2504;DP=103152;EAS_AF=0.3363;AMR_AF=0.3602;AFR_AF=0.4909;EUR_AF=0.4056;SAS_AF=0.4949;AA=|||unknown(NO_COVERAGE);VT=INDEL GT  1|0 0|1 0|1
3   10177   rs555500075 A   AC  100 PASS    AC=2130;AF=0.425319;AN=5008;NS=2504;DP=103152;EAS_AF=0.3363;AMR_AF=0.3602;AFR_AF=0.4909;EUR_AF=0.4056;SAS_AF=0.4949;AA=|||unknown(NO_COVERAGE);VT=INDEL GT  1|0 0|1 0|1
4   10177   rs548419688 A   AC  100 PASS    AC=2130;AF=0.425319;AN=5008;NS=2504;DP=103152;EAS_AF=0.3363;AMR_AF=0.3602;AFR_AF=0.4909;EUR_AF=0.4056;SAS_AF=0.4949;AA=|||unknown(NO_COVERAGE);VT=INDEL GT  1|0 0|1 0|1
基本上,我必须检查rsxxxxx在a.txt.gz和b.txt.gz中是否相互匹配

c、 txt.gz

10084625    rs123
10026407    rs456
d、 这是原始文件

514786698   10084625    491891820   4   12951   0.986   562 421
5221808     495944      1573768     4   664     0.261062   59   2
539535670   10026407    556933170   3   \N  \N  \N  \N
输出文件c.txt.gz+d.txt.gz=e.txt.gz

514786698   10084625    491891820   4   12951   0.986   562 421
5221808 \N  \N  \N  \N
539535670   10026407    556933170   3   \N  \N  \N  \N
514786698   10084625    491891820   4   12951   0.986   562 421
539535670   10026407    556933170   3   \N  \N  \N  \N
预期输出文件c.txt.gz+d.txt.gz=e.txt.gz

514786698   10084625    491891820   4   12951   0.986   562 421
5221808 \N  \N  \N  \N
539535670   10026407    556933170   3   \N  \N  \N  \N
514786698   10084625    491891820   4   12951   0.986   562 421
539535670   10026407    556933170   3   \N  \N  \N  \N

因此,它在d.txt.gz中写下了一行,而不是在c.txt.gz的第二行-495944中,使用awk和进程替换:

$ awk 'NR==FNR{a[$2];next}($3 in a){print "FOUND"}' <(zcat a.txt.gz ) <(zcat b.txt.gz)
FOUND
FOUND
FOUND
FOUND

awk '
NR==FNR {                            # first file hash to a on second field
    a[$2]
    next }                           # next record
($3 in a){                           # second file
    print "FOUND" }                  # print FOUND when found (more informative?)
' <(zcat a.txt.gz ) <(zcat b.txt.gz) # uncompress and use process substitution 
对于已编辑的数据和预期输出:

$ awk '
NR==FNR{ a[$1]; next }          # hash the first file, use $1 field as key
($2 in a)                       # second file, if $2 field value is found in a, 
                                # ($2 in a) evaluates to true 
                                # which initiates implicit printing of the record
' <(zcat c.txt.gz ) <(zcat d.txt.gz)

514786698   10084625    491891820   4   12951   0.986   562 421
539535670   10026407    556933170   3   \N  \N  \N  \N

在阅读了a.txt.gz之后,它在闪烁的指针处卡住了。您如何知道它卡住了并且没有继续运行?要调试shell脚本,请在开始处放置set-x。它将在执行时向您显示这些行,然后您可以看到它在做什么。grep的速度要快得多,因为它不必每次调用时都展开文件。顺便说一句,用[…]*结束模式没有意义。因为这与字符类的零重复匹配,所以它不会向搜索添加任何内容。在开始处似乎也没有任何指向[…]*的点。您应该只需要执行zgrep-q$p1/home/tdq/Bash/b.txt.gz谢谢,如果b.txt.gz很小,这就可以了,但是现在我注意到,当b.txt.gz变大~1G时,它仍然停留在闪烁的指针上。脚本似乎一直在读取b.txt.gz文件的所有行。我尝试了这个方法,实际使用了5m11.387s用户9m37.188s sys 0m18.260sIt。它解压缩a.txt.gz并将其散列到内存中。然后解压b.txt.gz并遍历每个记录,将其与内存中的散列a进行比较。我在OP中遗漏了一条退出规则吗?谢谢你的帮助,但我注意到当使用awk时,他们将数据写入了错误的输出文件。只是有些行是错误的数据,好像它没有正确地断线!你知道吗?我一点也不明白。它应该是什么?