StackOverflow上的一些好心人帮我找到了使用awk
的两个文件中的共同行:
awk 'NR==FNR{a[tolower($0)]; next} tolower($0) in a' 1.txt 2.txt
但是如何在两个单词排成一行的文件中找到常用词呢?
例如,假设我有1.txt
和这些单词:
apple
orange
butter
flower
然后2.txt
加上这些字:
dog cat Butter tower
如何返回butter
或Butter
?
我只是想找一下常用词。
这个grep
应该可以完成这项工作:
grep -oiwFf 1.txt 2.txt
Butter
或者这个简单的gnu awk
也可以:
awk -v RS='[[:space:]]+' 'NR==FNR {w[tolower($1)]; next} tolower($1) in w' 1.txt 2.txt
Butter
给定:
$ cat file1
apple
orange
butter
flower
$ cat file2
dog cat Butter tower
我会这样写:
awk 'FNR==NR{for(i=1;i<=NF;i++) words[tolower($i)]; next}
{for (i=1;i<=NF;i++) if (tolower($i) in words) print $i}
' file1 file2
注意,在FNR==NR
的情况下,有一个逐字段循环,用于处理每行可能有多个单词的文件。如果您知道情况并非如此,则可以简化为:
awk 'FNR==NR{words[tolower($1)]; next}
{for (i=1;i<=NF;i++) if (tolower($i) in words) print $i}
' file1 file2
如果这在Windows上不起作用,可能是rn
行结尾的问题。如果awk
使用RS=[n]
值,则r
留在一行末尾的所有单词上;butterr
不匹配butter
.
试题:
awk -v RS='[ rnt]' 'FNR==NR{words[tolower($0)]; next}
tolower($0) in words' file1 file2
链接中对WSL注释的注释:
在DOS上处理Unix文件的方法有很多。
创建file1
与DOS行结束如下:
$ printf 'applernorangernbutterrnflowerrn' >file1
现在你可以测试/看到文件有那些以cat -v
结尾的行:
$ cat -v file1
apple^M
orange^M
butter^M
flower^M
您还可以删除以sed
,perl
,awk
等结尾的行。下面是awk
从文件中删除r
:
$ cat -v <(awk 1 RS='rn' ORS='n' file1)
apple
orange
butter
flower
Ased
andperl
:
$ cat -v <(sed 's/r$//' file1)
#same
或
$ cat -v <(perl -0777 -lpe 's/rn/n/g' file1)
等。然后对awk-on-windows:
使用相同的结构awk 'your_awk_program' <(awk 1 RS='rn' ORS='n' file1) <(awk 1 RS='rn' ORS='n' file2)
缺点:虽然每个输入都被视为不同的逻辑文件,因此FNR==NR
awk测试仍然有效,但awk特殊变量FILENAME
在该过程中丢失了。如果您希望将FILENAME
与实际文件相关联,则需要在提供给awk之前对文件进行预处理,或者在awk脚本中处理r
。
您需要遍历每行(2.txt)的每个字段并检查:
awk 'NR==FNR{a[tolower($0)];next}{for(i=1;i<=NF;i++){if(tolower($i) in a){print $i}}}'
1.txt 2.txt
在awk中执行此操作的另一种方法是在处理第二个文件时在输入记录分隔符中添加空白:
awk 'NR==FNR{a[tolower($0)];next} tolower($0) in a' 1.txt RS="[n ]" 2.txt