我有一个文件(search.patterns),其中包含要搜索到其他 txt 文件列表中的模式列表。
搜索模式
home
dog
cat
文件1.txt
home 3
tiger 4
lion 1
文件2.txt
dolphin 6
jaguar 3
dog 1
文件3.txt
donkey 3
cat 4
horse 1
所以我希望在file1中搜索模式文件的第一行,在file2中搜索第二行,在file3中搜索第三行
输出:
home 3
dog 1
cat 4
我写了一些这样的代码:
for f in *.txt;
do
while IFS= read -r LINE;
do grep -f "$LINE" "$f" > "$f.out"
done < search.patterns
done
但是输出文件是空的
任何帮助,高度赞赏,谢谢
答案1
使用 GNU awk ( gawk
),您可以使用BEGINFILE
规则在每次输入文件更改时读取新模式:
$ gawk 'BEGINFILE{getline pat < "search.patterns"} $0 ~ pat' file\ {1..3}.txt
home 3
dog 1
cat 4
getline
例如,您应该真正检查是否返回新模式
gawk '
BEGINFILE {
if((getline pat < "search.patterns") <= 0) {
print "Error reading pattern" > "/dev/stderr"
exit 1
}
}
$0 ~ pat
' file\ {1..3}.txt
请注意,awk
模式是扩展正则表达式,类似于grep
with-E
选项支持的表达式。
您可以通过作为第一个文件awk
传递并适当地使用和将模式读入索引数组,或查找数组中的下一个模式,在非 GNU 中实现相同的效果。search.patterns
NR
FNR
答案2
使用bash
:
#!/bin/bash
files=( 'file 1.txt' 'file 2.txt' 'file 3.txt' )
while IFS= read -r pattern; do
grep -e "$pattern" "${files[0]}"
files=( "${files[@]:1}" )
done <search.patterns
测试它:
$ bash script.sh
home 3
dog 1
cat 4
该脚本将相关文件名保存在files
数组中,然后继续从search.patterns
文件中读取模式。对于每个模式,files
都会查询列表中的第一个文件。然后,处理后的文件将从列表中删除files
(在列表中产生新的第一个文件名)。
如果模式数量超过 中的文件数量files
,则会出现错误grep
。
答案3
您可以使用paste
该模式与文件进行匹配:
paste <(printf "%s\n" *.txt) search.patterns | while IFS=$'\t' read -r file pattern; do
grep -- "$pattern" "$file"
done
我假设文件名不包含制表符。