Bash比较输入数组和文本文件并更新文件

时间:2016-06-15 00:16:30

标签: arrays string bash compare

我读了一个字符串,根据分隔符将其拆分并将其存储到数组中。我想迭代一个文本文件并删除不包含我存储在数组中的字符串的行。假设我得到的数组是['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

我的文本文件是: foo grault bar xyzzy baz quz quux

我想删除行grault,xyzzy(因为它们不在数组中)并在末尾添加corge,因此我的结果文件将是: foo bar baz quz quux corge

我打算使用for循环遍历我的数组并使用grep添加文件中缺少的行,但是我应该如何删除数组中不存在但存在于文件中的行?

2 个答案:

答案 0 :(得分:0)

让我们定义已批准的字词列表:

$ 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"

    这定义了一个awk变量s,其中包含shell变量words的内容。

  • 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]仍为零,然后打印出来。

答案 1 :(得分:0)

如果你的原始文件是一个很好的文件,就像你可以做的第二个

(grep -f <good list> <bad list>; echo 'corge')

获取正确的列表,否则您可以尝试

(grep -f <(printf '%s\n' "${array[@]}") <bad file>; echo 'corge')

将使用进程替换使您的数组像grep可用于为您搜索文件的文件

这将只为您提供原始文件中单词列表中的行以及您已识别的corge行。如果你只是想让另一个文件与单词列表匹配,你可能会跳过所有的行匹配,只需将你的数组写入文件。