Bash Unix 搜索多个文件中的单词列表
Bash Unix search for a list of words in multiple files
我有一个单词列表,我需要检查一百多个文本文件。
我的 word 文件列表名为:word2search.txt.
此文本文件包含 N 个单词:
Word1
Word2
Word3
Word4
Word5
Word6
Wordn
到目前为止,我已经完成了这个 bash 文件:
#!/bin/bash
listOfWord2Find=/home/mobaxterm/MyDocuments/word2search.txt
while IFS= read -r listOfWord2Find
do
echo "$listOfWord2Find"
grep -l -R "$listOfWord2Find" /home/mobaxterm/MyDocuments/txt/*.txt
echo "================================================================="
done <"$listOfWord2Find"
结果不让我满意,我很难利用这个结果
Word1
/home/mobaxterm/MyDocuments/txt/new 6.txt
/home/mobaxterm/MyDocuments/txt/file1.txt
/home/mobaxterm/MyDocuments/txt/file2.txt
/home/mobaxterm/MyDocuments/txt/file3.txt
=================================================================
Word2
/home/mobaxterm/MyDocuments/txt/new 6.txt
/home/mobaxterm/MyDocuments/txt/file1.txt
=================================================================
Word3
/home/mobaxterm/MyDocuments/txt/new 6.txt
/home/mobaxterm/MyDocuments/txt/file4.txt
/home/mobaxterm/MyDocuments/txt/file5.txt
/home/mobaxterm/MyDocuments/txt/file1.txt
=================================================================
Word4
/home/mobaxterm/MyDocuments/txt/new 6.txt
/home/mobaxterm/MyDocuments/txt/file1.txt
=================================================================
Word5
/home/mobaxterm/MyDocuments/txt/new 6.txt
=================================================================
这就是我想看到的:
/home/mobaxterm/MyDocuments/txt/file1.txt : Word1, Word2, Word3, Word4
/home/mobaxterm/MyDocuments/txt/file2.txt : Word1
/home/mobaxterm/MyDocuments/txt/file3.txt : Word1
/home/mobaxterm/MyDocuments/txt/file4.txt : Word3
/home/mobaxterm/MyDocuments/txt/file5.txt : Word3
/home/mobaxterm/MyDocuments/txt/new 6.txt : Word1, Word2, Word3, Word4, Word5, Word6
我不明白为什么我的脚本不显示 Word6(有些文件包含这个 word6)。它停在 word5。为了避免这个问题,我添加了一个新行 blablabla(我肯定不会发现这个问题)。
如果你能帮我解决这个问题:)
谢谢。
建议的策略是每行扫描一次所有单词。
建议写gawk
脚本,标准Linuxawk
script.awk
FNR == NR { # Only in first file having match words list
matchWordsArr[++wordsCount] = [=10=]; # read match words into ordered array
matchedWordInFile[wordsCount] = 0; # reset matchedWordInFile array
}
FNR != NR { # Read line in inspected file
for (i in matchWordsArr) { # scan line for all match words
if ([=10=] ~ matchWordsArr[i]) matchedWordInFile[i]++; # if word is mached increment respective matchedWordInFile[i]
}
}
ENDFILE{ # on each file read completion
if (FNR != NR) { # if not first file
outputLine = sprintf("%s: ", FILENAME); # assign outputLine header to current fileName
for (i in matchWordsArr) { # iterate over matched words
if (matchedWordInFile[i] == 0) continue; # skip unmatched words
outputLine = sprintf("%s%s%s", outputLine, seprator, matchWordsArr[i]); # append matched word to outputLine
matchedWordInFile[i] = 0; # reset matched words array
seprator = ","; # set words list seperator ","
}
print outputLine;
}
outputLine = seprator = ""; # reset words list seperator "" and outputLine
}
输入.1.txt:
word1
word2
word3
输入.2.txt:
word3
word4
word5
输入.3.txt:
word3
word7
word8
words.txt
word2
word1
word5
word4
运行:
$ awk -f script.awk words.txt input.*.txt
input.1.txt: word2,word1
input.2.txt: word5,word4
input.3.txt:
另一种更优雅的方法来搜索每个文件中的所有单词。一次一个文件。
使用 grep
命令多模式选项 -f, --file=FILE
,并打印与 -o, --only-matching
匹配的行
然后将生成的单词通过管道传送到 csv
列表中。
像这样:
script.sh
#!/bin/bash
for currFile in $*; do
matched_words_list=$(grep --only-matching --file=$WORDS_LIST $currFile |sort|uniq|awk -vORS=', ' 1|sed "s/, $//")
printf "%s : %s\n" "$currFile" "$matched_words_list"
done
script.sh输出
在环境变量中传递单词列表文件:WORDS_LIST
将检查的文件列表作为参数列表传递input.*.txt
export WORDS_LIST=./words.txt; ./script.sh input.*.txt
input.1.txt : word1, word2
input.2.txt : word4
input.3.txt :
解释:
使用 words.txt:
word2
word1
word5
word4
使用输入。1.txt:
word1
word2
word3
word3
word1
word3
和管道按摩 grep
命令
grep --file=words.txt -o input.1.txt |sort|uniq|awk -vORS=, 1|sed s/,$//
word1,word2
输出 1
在检查的文件输入中列出来自 words.txt 的所有匹配词。1.txt
grep --file=words.txt -o input.1.txt
word1
word2
word1
输出 2
在检查的文件输入中列出来自 words.txt 的所有匹配词。1.txt
比排序输出词列表
grep --file=words.txt -o input.1.txt|sort
word1
word1
word2
输出 3
在检查的文件输入中列出来自 words.txt 的所有匹配词。1.txt
比排序输出词列表
比删除重复的词
grep --file=words.txt -o input.1.txt|sort|uniq
word1
word2
输出 4
在检查的文件输入中列出来自 words.txt 的所有匹配词。1.txt
比排序输出词列表
比删除重复的词
然后从独特的单词
创建一个csv
列表
grep --file=words.txt -o input.1.txt|sort|uniq|awk -vORS=, 1
word1,word2,
输出 5
在检查的文件输入中列出来自 words.txt 的所有匹配词。1.txt
比排序输出词列表
比删除重复的词
然后从独特的单词
创建一个csv
列表
比从 csv
列表中删除尾随 ,
grep --file=words.txt -o input.1.txt|sort|uniq|awk -vORS=, 1|sed s/,$//
word1,word2
只需 grep:
grep -f list.txt input.*.txt
-f FILENAME
允许使用带有模式的文件供 grep 搜索。
如果要显示文件名和匹配项,除此之外还要传递 -H
:
grep -Hf list.txt input.*.txt
我有一个单词列表,我需要检查一百多个文本文件。
我的 word 文件列表名为:word2search.txt.
此文本文件包含 N 个单词:
Word1
Word2
Word3
Word4
Word5
Word6
Wordn
到目前为止,我已经完成了这个 bash 文件:
#!/bin/bash
listOfWord2Find=/home/mobaxterm/MyDocuments/word2search.txt
while IFS= read -r listOfWord2Find
do
echo "$listOfWord2Find"
grep -l -R "$listOfWord2Find" /home/mobaxterm/MyDocuments/txt/*.txt
echo "================================================================="
done <"$listOfWord2Find"
结果不让我满意,我很难利用这个结果
Word1
/home/mobaxterm/MyDocuments/txt/new 6.txt
/home/mobaxterm/MyDocuments/txt/file1.txt
/home/mobaxterm/MyDocuments/txt/file2.txt
/home/mobaxterm/MyDocuments/txt/file3.txt
=================================================================
Word2
/home/mobaxterm/MyDocuments/txt/new 6.txt
/home/mobaxterm/MyDocuments/txt/file1.txt
=================================================================
Word3
/home/mobaxterm/MyDocuments/txt/new 6.txt
/home/mobaxterm/MyDocuments/txt/file4.txt
/home/mobaxterm/MyDocuments/txt/file5.txt
/home/mobaxterm/MyDocuments/txt/file1.txt
=================================================================
Word4
/home/mobaxterm/MyDocuments/txt/new 6.txt
/home/mobaxterm/MyDocuments/txt/file1.txt
=================================================================
Word5
/home/mobaxterm/MyDocuments/txt/new 6.txt
=================================================================
这就是我想看到的:
/home/mobaxterm/MyDocuments/txt/file1.txt : Word1, Word2, Word3, Word4
/home/mobaxterm/MyDocuments/txt/file2.txt : Word1
/home/mobaxterm/MyDocuments/txt/file3.txt : Word1
/home/mobaxterm/MyDocuments/txt/file4.txt : Word3
/home/mobaxterm/MyDocuments/txt/file5.txt : Word3
/home/mobaxterm/MyDocuments/txt/new 6.txt : Word1, Word2, Word3, Word4, Word5, Word6
我不明白为什么我的脚本不显示 Word6(有些文件包含这个 word6)。它停在 word5。为了避免这个问题,我添加了一个新行 blablabla(我肯定不会发现这个问题)。
如果你能帮我解决这个问题:) 谢谢。
建议的策略是每行扫描一次所有单词。
建议写gawk
脚本,标准Linuxawk
script.awk
FNR == NR { # Only in first file having match words list
matchWordsArr[++wordsCount] = [=10=]; # read match words into ordered array
matchedWordInFile[wordsCount] = 0; # reset matchedWordInFile array
}
FNR != NR { # Read line in inspected file
for (i in matchWordsArr) { # scan line for all match words
if ([=10=] ~ matchWordsArr[i]) matchedWordInFile[i]++; # if word is mached increment respective matchedWordInFile[i]
}
}
ENDFILE{ # on each file read completion
if (FNR != NR) { # if not first file
outputLine = sprintf("%s: ", FILENAME); # assign outputLine header to current fileName
for (i in matchWordsArr) { # iterate over matched words
if (matchedWordInFile[i] == 0) continue; # skip unmatched words
outputLine = sprintf("%s%s%s", outputLine, seprator, matchWordsArr[i]); # append matched word to outputLine
matchedWordInFile[i] = 0; # reset matched words array
seprator = ","; # set words list seperator ","
}
print outputLine;
}
outputLine = seprator = ""; # reset words list seperator "" and outputLine
}
输入.1.txt:
word1
word2
word3
输入.2.txt:
word3
word4
word5
输入.3.txt:
word3
word7
word8
words.txt
word2
word1
word5
word4
运行:
$ awk -f script.awk words.txt input.*.txt
input.1.txt: word2,word1
input.2.txt: word5,word4
input.3.txt:
另一种更优雅的方法来搜索每个文件中的所有单词。一次一个文件。
使用 grep
命令多模式选项 -f, --file=FILE
,并打印与 -o, --only-matching
然后将生成的单词通过管道传送到 csv
列表中。
像这样:
script.sh
#!/bin/bash
for currFile in $*; do
matched_words_list=$(grep --only-matching --file=$WORDS_LIST $currFile |sort|uniq|awk -vORS=', ' 1|sed "s/, $//")
printf "%s : %s\n" "$currFile" "$matched_words_list"
done
script.sh输出
在环境变量中传递单词列表文件:WORDS_LIST
将检查的文件列表作为参数列表传递input.*.txt
export WORDS_LIST=./words.txt; ./script.sh input.*.txt
input.1.txt : word1, word2
input.2.txt : word4
input.3.txt :
解释:
使用 words.txt:
word2
word1
word5
word4
使用输入。1.txt:
word1
word2
word3
word3
word1
word3
和管道按摩 grep
命令
grep --file=words.txt -o input.1.txt |sort|uniq|awk -vORS=, 1|sed s/,$//
word1,word2
输出 1
在检查的文件输入中列出来自 words.txt 的所有匹配词。1.txt
grep --file=words.txt -o input.1.txt
word1
word2
word1
输出 2
在检查的文件输入中列出来自 words.txt 的所有匹配词。1.txt
比排序输出词列表
grep --file=words.txt -o input.1.txt|sort
word1
word1
word2
输出 3
在检查的文件输入中列出来自 words.txt 的所有匹配词。1.txt
比排序输出词列表
比删除重复的词
grep --file=words.txt -o input.1.txt|sort|uniq
word1
word2
输出 4
在检查的文件输入中列出来自 words.txt 的所有匹配词。1.txt
比排序输出词列表
比删除重复的词
然后从独特的单词
创建一个csv
列表
grep --file=words.txt -o input.1.txt|sort|uniq|awk -vORS=, 1
word1,word2,
输出 5
在检查的文件输入中列出来自 words.txt 的所有匹配词。1.txt
比排序输出词列表
比删除重复的词
然后从独特的单词
创建一个csv
列表
比从 csv
列表中删除尾随 ,
grep --file=words.txt -o input.1.txt|sort|uniq|awk -vORS=, 1|sed s/,$//
word1,word2
只需 grep:
grep -f list.txt input.*.txt
-f FILENAME
允许使用带有模式的文件供 grep 搜索。
如果要显示文件名和匹配项,除此之外还要传递 -H
:
grep -Hf list.txt input.*.txt