逐行读取并使用 grep 执行 cat

逐行读取并使用 grep 执行 cat

我正在构建一个脚本来从文件内容加载,然后在另一个文件中使用 cat 和 grep 。问题是执行 grep 时没有显示任何值。如果我手动执行命令,它将检索数据。

我已经使用了 while 但问题是一样的。 output6.txt 始终为空。 echo 似乎有效,所以这似乎是 grep 或 cat 问题。

来自 BlockspamCLIs.txt 的示例我有以下值:

4412345 
441236 
2367890

All_events.csv 文件示例

1,441236,20220909120909,test
2,441237,20220909120909,test
3,441232,20220909120909,test
4,44136,20220909120909,test
5,2367890,20220909120909,test

作为输出,我希望检索、存储并记录在包含数字的 CSV 文件内,例如:

1,441236,20220909120909,test
5,2367890,20220909120909,test

我的脚本:

for i in `cat BlockspamCLIs.txt`
do
   grep $i *_All_events.csv >> output6.txt
   
   echo $i
done

先感谢您。

答案1

首先,请不要使用 shell 脚本来完成此类任务,速度慢且容易出错。无论如何,grep已经可以做你想做的事了:

grep -f BlockspamCLIs.txt *_All_events.csv >> output6.txt

man grep

       -f FILE, --file=FILE
              Obtain patterns from FILE, one per line.   If  this  option  is
              used  multiple  times  or  is  combined  with the -e (--regexp)
              option, search for all patterns given.  The empty file contains
              zero patterns, and therefore matches nothing.

接下来,如果您确实使用 shell 循环来迭代文件的内容,永远不要这样做for i in $(cat file)。并且,您必须始终引用变量以避免各种问题。例如,如果 中的任何行BlockspamCLIs.txt包含空格,您的命令将不起作用。

也就是说,如果您的行没有空格或 shell 通配符,则您显示的命令将起作用。最好这样写:

while IFS= read -r i; do
    grep -e "$i" -- *_All_events.csv >> output6.txt
    printf '%s\n' "$i"
done < BlockspamCLIs.txt

答案2

使用专门为执行这些操作而构建的工具:

$ csvgrep -H -f BlockspamCLIs.txt -c 2 All_events.csv | tail -n +2
1,441236,20220909120909,test
5,2367890,20220909120909,test

csvgrep实用程序是csvkit,我在这里使用它从无标头 ( -H) CSV 文件中提取所有记录All_events.csv,其中第二个字段 ( -c 2) 与另一个文件 ( ) 中的任何字符串匹配-f BlockspamCLIs.txt

由于输入文件是无标头 CSV 文件,csvgrep因此将在生成的 CSV 输出中添加一个虚拟标头,我们将其删除tail(您也可以使用sed 1d或任何其他命令来删除第一行并在未修改的情况下传递其余行)。

由于我们使用支持 CSV 的工具,因此输入不限于“简单”CSV 数据,还可以处理包含嵌入逗号、引号和换行符的字段的输入。

即使文件是 DOS 文本格式,此方法也有效。

相关内容