Linux Grep功能不停止与头管

Linux Grep功能不停止与头管,linux,bash,shell,grep,Linux,Bash,Shell,Grep,因此,我目前正在尝试从特定目录中的随机文件中grep一个结果。grepping工作正常,预期的输出文件按预期填充,但由于某些原因,即使输出文件已填充,该过程也不会停止。这是grep命令,程序似乎被卡住了 searchFILE(){ case $2 in pref) echo "Populating output file: $3-$1.data.out" dataOutputFile="$3-$1.data.out" zgrep -a "\"someParameter\"

因此,我目前正在尝试从特定目录中的随机文件中grep一个结果。grepping工作正常,预期的输出文件按预期填充,但由于某些原因,即使输出文件已填充,该过程也不会停止。这是grep命令,程序似乎被卡住了

searchFILE(){
case $2 in
pref)
    echo "Populating output file: $3-$1.data.out"
    dataOutputFile="$3-$1.data.out"
    zgrep -a "\"someParameter\"\:\"$1\"" /folder/anotherFolder/filetemplate.log.* | zgrep -a "\"parameter2\"\:\"$3\"" | head -1 > $dataOutputFile
;;
*)
    echo "Unrecognized command"
;;
esac
echo "Query finished"
}

当前发生的情况是,输出文件按照预期使用头管道填充,但由于某些原因,我没有收到“queryfinished”消息,而且这个过程似乎一点也没有停止。

我看到zcat myZippedFile | grep无论什么范例都有更好的性能结果…

您需要尝试的第一个区别是管道具有| head-z--lines=1

原因是以null结尾的行而不是换行(以防万一)。 我下面的示例脚本有效(删除case语句使其更简单)。如果我持有1美元2美元的内部函数,事情就会出错。我使用参数$names并且只使用$1$2$@一次,因为如果我不这样做,它对我来说也会出错,并且在任何情况下,您都可以切换到$@并捕获参数。脚本本身中的$@与bash函数中的参数不同

grep以任意顺序搜索2个或多个参数表示使用grep两次;在您的情况下,zgrep | grep。第二个grep是正常grep!你只需要第一个grep被zgrep解压。当bash case吓跑了人们时,如果你放弃case陈述,你的问题就简单多了:bash总是一个丑女人,适合写短脚本

zgrep搜索文本或压缩文本,但LINUX样式的换行与WINDOWS样式的换行不同。因此,请使用dos2unix来转换文件,以便换行符工作。我使用压缩文件仅仅是因为它很奇怪,而且很少看到zgrep,所以在一个带有压缩文件的shell脚本中演示了它!它对我有用。我改变了一些东西,比如>>和“sort-u”,但是你显然可以把它们改回来

#!/usr/bin/env bash
# Search for egA AND egB  using option go
# COMMAND LINE: ./zgrp egA go egB
A="$1"
cOPT="$2" # expecting case go
B="$3"
LOG="./filetemplate.log" # use parameters for long names.

# Generate some data with gzip and delete the temporary file.
echo "\"pramA\":\"$A\"  \"pramB\":\"$B\"" >> $B$A.tmp
rm -f ${LOG}.A; tar czf ${LOG}.A $B$A.tmp
rm -f $B$A.tmp
# Use paramaterise $names not $1 etc because you may want to do shift etc
searchFILE()
{
    outFile="$B-$A.data.out"
    case $cOPT in
        go) # This is zgrep | grep   NOT zgrep | zgrep 
            zgrep -a "\"pramA\":\"$A\"" ${LOG}.* | grep -a "\"pramB\":\"$B\"" | head -z --lines=1 >> $outFile
            sort -u $outFile > ${outFile}.sorted  # sort unique on your output.
            ;;
        *) echo -e "ERROR second argument must be go.\n Usage: ./zgrp egA go egB"
            exit 9
            ;;
    esac

    echo -e "\n ============ Done: $0 $@      Fin. ============="
}
searchFILE "$@"

cat ${outFile}.sorted

grep
不知道
head-n1
不再从管道中读取数据,直到它尝试写入管道,只有在找到另一个匹配项时才会这样做。流程之间没有直接的通信。它最终将停止,但只有在读取所有数据后,才能找到第二个匹配项,并且
写入
失败,出现
EPIPE
,或者发生其他错误

您可以在这样一个简单的管道中看到这种情况:

cat /dev/urandom | grep -ao "12[0-9]" | head -n1
对于足够罕见的模式,您将观察到输出和退出之间的延迟

一种解决方案是改变停止条件。不要像管道那样等待
SIGPIPE
,而是使用
-m1
选项等待
grep
匹配一次:

cat /dev/urandom | grep -ao -m1 "12[0-9]"

生产一条管线时,管线不会立即停止。您能否检查
zgrep
是否仍在运行并尝试查找更多匹配项?我猜数据量很大,匹配项很少
zgrep
将一直运行,直到输入耗尽,或者它尝试写入另一个匹配项并获得SIGPIPE。嗯,数据实际上非常大,但我只对一个结果感兴趣。一旦找到一个匹配项,head-1不应该停止grep吗?我的意思是,我知道,由于文件按预期填充,已经找到了预期的结果,但出于某种原因,grep似乎根本没有停止。