a.txt包含单词,b.txt包含字符串。
我想知道b.txt中有多少字符串以a.txt中的单词开头或结尾。
我在GREP用户手册中找到了这个: "假设我想搜索整个单词,而不是单词的一部分? grep -w'你好' * 仅搜索整个单词的'hello'实例;它与'奥赛罗'不符。要获得更多控制权,请使用'\ _<'和'>'来匹配单词的开头和结尾。例如:
grep 'hello\>' *
仅搜索以'hello'结尾的单词,因此它匹配单词'Othello'。"
但我不知道如何修改它来解决我的问题。
示例:a.txt
apple
peach
potato
green
big
pink
b.txt
greenapple
bigapple
rottenapple
pinkpeach
xxlpotatoxxx
输出
ends.txt
3 apple greenapple bigapple rottenapple
1 peach pinkpeach
starts.txt
1 green greenapple
1 big bigapple
1 pink pinkpeach
但是由于a.txt包含大约50K行,而b.txt包含超过100M行,我认为,grep是唯一的解决方案。
答案 0 :(得分:4)
最好的办法是编写一个脚本,该脚本将循环遍历包含模式的文件的每一行,并为另一个文件中的模式编译grep
:
以下内容将获取 startsWith 字符串:
while read -r w; do
start=($(grep "^${w}" b.txt));
(( ${#start[@]} != 0 )) && echo "${#start[@]} $w ${start[@]}";
done < a.txt
对你的样本输入执行它,它会产生:
1 green greenapple
1 big bigapple
1 pink pinkpeach
同样,你可以编写另一个单行程来获得 endsWith 字符串:
while read -r w; do
end=($(grep "${w}$" b.txt));
(( ${#end[@]} != 0 )) && echo "${#end[@]} $w ${end[@]}";
done < a.txt
会产生:
3 apple greenapple bigapple rottenapple
1 peach pinkpeach
编辑:如果要将输出重定向到单独的文件,可以在一个循环中执行这两个部分:
> startswith.txt # Truncate the output files to begin with
> endswith.txt
while read -r w; do
start=($(grep "^${w}" b.txt));
(( ${#start[@]} != 0 )) && echo "${#start[@]} $w ${start[@]}" >> startswith.txt;
end=($(grep "${w}$" b.txt));
(( ${#end[@]} != 0 )) && echo "${#end[@]} $w ${end[@]}" >> endswith.txt;
done < a.txt
答案 1 :(得分:3)
awk '
NR == FNR {word[$1]; next}
{
for (w in word) {
if ($1 ~ "^" w) starts[w] = starts[w] $1 " "
if ($1 ~ w "$") ends[w] = ends[w] $1 " "
}
}
END {
for (w in ends) {
n = split(ends[w], a)
print n, w, ends[w] > "ends.txt"
}
for (w in starts) {
n = split(starts[w], a)
print n, w, starts[w] > "starts.txt"
}
}
' a.txt b.txt
$ cat ends.txt
3 apple greenapple bigapple rottenapple
1 peach pinkpeach
$ cat starts.txt
1 pink pinkpeach
1 big bigapple
1 green greenapple
答案 2 :(得分:1)
您可以使用简单的bash脚本:
#!/bin/bash
INPUT=a.txt
SEARCH=b.txt
OUTS=starts.txt
OUTE=ends.txt
while read line ; do
echo -n "$line " >> "$OUTS"
echo -n "$line " >> "$OUTE"
grep "$line\>" "$SEARCH" | xargs >> "$OUTE"
grep "\<$line" "$SEARCH" | xargs >> "$OUTS"
done < "$INPUT"
(这不会打印行前面的匹配数量)
答案 3 :(得分:1)
这个单行
for a in `cat a.txt` ; do echo $a ; grep -c $a\\\>\\\|\\\<$a b.txt ; done
生成此输出:
apple
3
peach
1
potato
0
green
1
big
1
pink
1
虽然它不是替代品产生的漂亮输出,但它是简洁的,只在a.txt