假设我有两个文件a.txt
和b.txt
.我想找到a.txt
其中出现的所有单词b.txt
。
有具体的命令可以做到这一点吗?
答案1
使用bash
和zsh
的一些实现ksh
:
comm -12 <(tr -s '[:space:]' '[\n*]' < a.txt | sort -u) \
<(tr -s '[:space:]' '[\n*]' < b.txt | sort -u)
那里,单词是一个非空格字符序列(请注意,对于 GNU tr
,它不适用于多字节空格字符)。
comm
查找两个已排序文件之间的公共行。如果没有选项,它会打印 3 列:仅在 file1 中的行、仅在 file2 中的行以及两者共有的行。您添加-1
, -2
,-3
以从输出中删除相应的列。所以comm -12
只留下第三列(公共线)。
tr -s '[:space:]' '[\n*]'
t拼音任何s类的字符序列space
换行,将每个单词在自己的线路上。
sort -u
tr
对 的输出进行排序并删除重复项。
进程替换将命令<(...)
的输出通过管道传输tr|sort
到comm
.
和zsh
:
w1=($(<a.txt)) w2=($(<b.txt))
print -rl -- ${(u)${w1:*w2}}
那里,单词是除空格、制表符、nul 和换行符之外的字符序列(默认值为$IFS
)。
$(<a.txt)
$(cat a.txt)
是where的优化版本,zsh
无需调用即可自行读取文件内容cat
,因为它没有被引用,所以它会进行分词(但与其他 shell 不同,不会进行通配)。
因此w1
和是包含和w2
中所有单词的数组。a.txt
b.txt
${w1:*w2}
是一个 zsh 运算符,它给出两个数组的交集(两个数组共有的元素)。(u)
是保留唯一元素(删除重复项)的参数扩展标志。
print -rl
每行打印每个参数一个。
答案2
# Create dummy text file containing two words
$ echo -e "overflow\ngrep" > b
# Search in file for lines containing one word from file b
$ grep --color --fixed-strings --file b /usr/share/dict/words
我的系统上的结果:
overflow
overflow's
overflowed
overflowing
overflows
添加--仅匹配(-o) 参数仅获取单词而不是它们出现的整行。
答案3
假设文件中的单词由 LF 分隔,并且单词仅由“nice”字符组成,并且 b.txt 中没有最后一个 LF 杂散,那么
egrep `tr '\n' '|' < b.txt` a.txt
可能会成功。
答案4
虽然不是按单词级别进行工作,但更多的是按行进行工作,这可能对您或其他寻求答案的人有用。
diff --left-column --from-file=a.txt --to-file=b.txt
比较文件 a.txt 和文件 b.txt,仅输出公共行。