我已经在字符串中读取,根据定界线将其拆分,然后将其存储到数组中。我想通过文本文件迭代并删除不包含我存储在数组中的字符串的行。说我由此产生的数组是['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
我的文本文件是:
foo
grault
bar
xyzzy
baz
quz
quux
我想删除行Groult,Xyzzy(因为它们不在数组中),并在末尾添加Corge,因此我的结果文件将是:
foo
bar
baz
quz
quux
corge
我打算使用for循环通过我的数组迭代并使用grep添加文件中缺少的行,但是我应该如何删除数组中不存在但存在于文件中的行?
让我们定义批准的单词列表:
$ words='foo bar baz qux quux corge'
现在,让我们从 file
中删除任何不在 words
中的单词:
$ awk -v s="$words" 'BEGIN{split(s,a,/ /); for (i in a) b[a[i]]} ($0 in b){b[$0]++;print}' file
foo
bar
baz
quux
如果我们要删除 words
中的任何单词,并且还添加 words
中不在 file
中的任何单词,则:
$ awk -v s="$words" 'BEGIN{split(s,a,/ /); for (i in a) b[a[i]]} ($0 in b){b[$0]++;print} END{for (w in b) if (b[w]==0) print w}' file
foo
bar
baz
quux
corge
qux
它如何工作
-v s="$words"
这定义了具有Shell变量
words
的内容的AWK变量s
。BEGIN{split(s,a,/ /); for (i in a) b[a[i]]}
在读取
file
之前,这将s
中的单词分为数组a
,其值是这些单词。然后,我们使用每个单词的一个键创建一个关联数组b
。($0 in b){b[$0]++;print}
当我们通过
file
阅读时,如果该行与b
中的一个单词匹配,请增加该单词出现的次数的数量,并打印单词。END{for (w in b) if (b[w]==0) print w}
我们读完文件后,如果未打印数组
b
中的任何单词,那就是其计数b[w]
仍然为零,然后打印。
如果您的原始内容在一个不错的文件中,那么您可以做
(grep -f <good list> <bad list>; echo 'corge')
要获取正确的列表,否则您可以尝试
(grep -f <(printf '%sn' "${array[@]}") <bad file>; echo 'corge')
将使用进程替换来使您的数组就像GREP可以用来为您搜索文件的文件
这将只为您从原始文件中的单词列表中的行提供,以及您已确定的corge
。如果您只希望另一个文件匹配单词列表,尽管您可能会跳过所有匹配行,然后将您的数组写入文件。