我有一个带有五列的制表符分隔文本文件 (animals.txt):
302947298 2340974238 0 0 cat
345098948 8345988989 0 0 dog
098982388 2098340923 0 0 fish
932840923 0923840988 0 0 parrot
Run Code Online (Sandbox Code Playgroud)
我有另一个文件,mess.txt.gz,它是使用 GNU zip(.gz 文件)压缩的。它基本上看起来像一串巨大的字母:
sdihfoiahdfosparrotdhiafoihsdfoijaslkdogoieufoiweuf
Run Code Online (Sandbox Code Playgroud)
基本上,对于制表符分隔的文本文件中的每一行,我想查看此 .gz 文件中是否存在任何动物名称。
理想情况下,它会返回如下内容:
302947298 2340974238 0 0 cat no
345098948 8345988989 0 0 dog yes
098982388 2098340923 0 0 fish no
932840923 0923840988 0 0 parrot yes
Run Code Online (Sandbox Code Playgroud)
目前我正在做以下事情:
gunzip -cd mess.txt.gz | grep cat
gunzip -cd mess.txt.gz | grep dog
Run Code Online (Sandbox Code Playgroud)
为了自动化,我尝试了以下方法:
cat animals.txt | awk '{print $5}' > animal_names.txt
cat animal_names.txt | while read line
do
gunzip -cd mess.txt.gz | grep $line > output.txt
done
Run Code Online (Sandbox Code Playgroud)
我也试过:
cat animal_names.txt | while read line
do
if [ gunzip -cd mess.txt.gz | grep $line ]
then
echo "Yes"
else
echo "No"
fi
; do
done > output.txt
Run Code Online (Sandbox Code Playgroud)
在 bash 中执行此操作的最佳方法是什么?
您可以一次性将所有搜索字符串zgrep -Ff -传递给:
cut -f5 animals.txt |
zgrep -Ff - mess.txt.gz
Run Code Online (Sandbox Code Playgroud)
该-F选项说要查找文字字符串,而不是正则表达式(如果输入包含点或其他正则表达式元字符,则可以避免误报,此外,速度会明显加快)并-f -说要从标准输入(即从管道中)读取搜索模式cut)。
如果您想要匹配动物的列表,请添加一个-o选项和一个简短的后处理步骤;
cut -f5 animals.txt |
zgrep -Ff - -o mess.txt.gz |
sort | uniq -c
Run Code Online (Sandbox Code Playgroud)
您可以替换| uniq -c只有-u如果你不在乎有多少是每个。
这在带有 GNU 的 Linux 上按预期工作grep,但 macOS(因此可能通常是 *BSD)grep -o仅在与-f -. 如果您需要 *BSD 可移植性,我会选择这里的其他解决方案之一(目前有sed一个用于 Awk,一个用于 Awk)。
| 归档时间: |
|
| 查看次数: |
67 次 |
| 最近记录: |