使用grep读取行时

5

我会尝试使用grep和while命令来报告找到的行。

我知道你可以使用以下命令来从inputs.txt文件中比较一系列字符串,并在目标文件中查找它们:

grep -f inputs.txt file_to_check

我希望能够循环读取输入字符串的每一行并进行grep操作。
因此,我尝试了以下方法:
cat inputs.txt | while read line; do if grep "$line" filename_to_check; then echo "found"; else echo "not found"; fi; done

当我将输出重定向到文件时,这不会返回任何内容。
while read line
do
if grep "$line" file_to_check
  then echo "found"
else 
  echo "not found"
fi
done < inputs.txt

与第一个类似,但我发现这种方式更好。

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

not found
not found
not found
.
. etc.

我需要的是一个能够迭代每一行并使用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.

读取测试命令或 [ - karakfa
4个回答

7

您也可以使用&&||操作符:

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

grep命令的-q参数仅输出状态码:

  • 如果找到$line,则输出0(真),&&后面的命令将被评估
  • 如果未找到,则输出1(假),||后面的命令将被评估

2
你可以将最终解决方案重写为:
# 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}")

0

嗯,您的 if 语句相当随意,您可能需要稍微整理一下以便于 bash 能够读取它。例如:

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

如果grep命令找到了这一行,那么这个if语句将会被判断为真,因为它会输出这一行并且不等于""或空字符串。


谢谢,我发现文件中有特殊的回车符,grep不知道如何处理。所以我通过VIM将内容复制到另一个测试文件中,并报告了我想要的结果。@Skyler,你的例子很有帮助,但它给出了一些奇怪的输出,即使在我的新文件上进行了测试也是如此。使用以下命令的输出:while read line; do if [ $(grep "$line" file_to_check) != "" ]; then echo "found: $line" else echo "not found: $line" fi done < inputs.txt 给出bash: [: !=: unary operator expected not found: item1 bash: [: !=: unary operator expected not found: item2 等。 - Joshua
抱歉,@Joshua,$(command) 应该用双引号括起来,已更新答案。 - Skyler
@Joshua 如果文件包含回车符,请使用 dos2unix 将其转换为普通的 Unix 换行符。 - Barmar
谢谢,那个双引号是我的错。我想我已经解决了我的问题,并会研究dos2unix。我开始使用cat inputs.txt | tr -d '\r' > newinputs.txt,这也很好用。 - Joshua

0
这是我的最终解决方案:
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

再次感谢!


不要写成 if [ "$(grep "$line" filename)" != "" ],直接写成 if grep -q "$line" filename - William Pursell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接