bash 使用 grep 读取行时

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35636229/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 14:19:03  来源:igfitidea点击:

While read line with grep

bashif-statementwhile-loopgrep

提问by Joshua

I am trying to report lines found using grep and while.

我正在尝试报告使用 grep 和 while 找到的行。

I know you can use the following to compare a list of strings from inputs.txt and find them in your target file like so:

我知道您可以使用以下内容来比较来自 input.txt 的字符串列表,并在您的目标文件中找到它们,如下所示:

grep -f inputs.txt file_to_check

What I want is to read each line of the inputted strings and grep them individual in a loop.

我想要的是读取输入字符串的每一行并在循环中单独grep它们。

So I have tried the following methods:

所以我尝试了以下方法:

cat inputs.txt | while read line; do if grep "$line" filename_to_check; then echo "found"; else echo "not found"; fi; done

This returns nothing when I redirect the output to a file.

当我将输出重定向到文件时,这不会返回任何内容。

while read line
do
if grep "$line" file_to_check
  then echo "found"
else 
  echo "not found"
fi
done < inputs.txt

Same as the first one but from what I found is better to do.

与第一个相同,但从我发现的更好。

I know it iterates line by line because I can replace grep with echo $line and it prints each line; but either method doesn't return anything like grep -f above, instead it shows:

我知道它会逐行迭代,因为我可以用 echo $line 替换 grep 并打印每一行;但任一方法都不会返回类似 grep -f 的内容,而是显示:

not found
not found
not found
.
. etc.

So what I'm looking for is something where it will iterate through each line and check it via grep using an if statement to determine if grep has actually found it or not. I know I may not have all proper logic but the output for what I want should look something like:

所以我正在寻找的是它会遍历每一行并通过 grep 使用 if 语句检查它以确定 grep 是否真的找到它的东西。我知道我可能没有所有正确的逻辑,但我想要的输出应该是这样的:

Found *matching line in file_to_check* 
Found *matching line in file_to_check*
Not Found $line *(string that does not match)*
.
. etc.

回答by SLePort

You can also use &&and ||operators :

您还可以使用&&||运算符:

while read line; do
         grep -q "$line" file_to_check  && echo "$line found in file_to_check" || echo "$line not found in file_to_check"
done < inputfile > result.txt

The -qparameter of the grep just outputs a status code :

-qgrep的参数只是输出一个状态码:

  • if $lineis found, it outpouts 0(True) the command after &&will be evaluated
  • if not found, it outputs 1(False) the command after ||will evaluated
  • 如果$line找到,它将输出0(真)之后的命令&&将被评估
  • 如果未找到,则输出1(False)||后将评估的命令

回答by Walter A

You can rewrite your final solution into

您可以将最终解决方案重写为

# Do not need this thanks to tr: file=$(dos2unix inputs.txt)

# Use -r so a line with backslashes will be showed like you want
while read -r line
do 
   # Not empty? Check with test -n
   if [ -n "$(grep "${line}" filename)" ]; then 
      echo "found: ${line}"
   else
      echo "not found: ${line}"
   fi 
done < <(tr -d "\r" < "${file}")

回答by Skyler

Well, your if statement is pretty free form, you might need to clean it up a bit for bash to be able to read it. For example:

好吧,您的 if 语句是非常自由的形式,您可能需要对其进行一些清理,以便 bash 能够读取它。例如:

if [ "$(grep "$line" file_to_check)" != "" ]; then
    echo "found:     $line"
else
    echo "not found: $line"
fi

This if statement will evaluate true if the grep command finds the line, because if it does it will spit the line out and will not be equal to "", or an empty string.

如果 grep 命令找到该行,则此 if 语句将评估为真,因为如果找到该行,它将吐出该行并且不等于 "" 或空字符串。

回答by Joshua

Here's my final solution:

这是我的最终解决方案:

file=$(dos2unix inputs.txt)
new_file=$file

while read line
do 
  if [ "$(grep "$line" filename)" != "" ]
    then echo "found: $line"
  else echo "not found: $line"
  fi 
done <$new_file

Thanks again!

再次感谢!