bash脚本:检查一个文件中的所有单词是否包含在另一个文件中,否则发出错误

时间:2013-05-28 11:59:47

标签: bash compare diff

我想知道你是否可以提供帮助。我是bash脚本的新手。

我希望能够比较两个列表。 File1.txt将包含许多参数的列表,file2.txt将只包含这些参数的一部分。

FILE1.TXT

dbipAddress=192.168.175.130
QAGENT_QCF=AGENT_QCF
QADJUST_INVENTORY_Q=ADJUST_INVENTORY_Q
QCREATE_ORDER_Q=CREATE_ORDER_Q
QLOAD_INVENTORY_Q=LOAD_INVENTORY_Q

FILE2.TXT

AGENT_QCF
ADJUST_INVENTORY_Q
CREATE_ORDER_Q

我想检查file1.txt中的所有Q是否都包含在file2.txt中(在=之后)。如果不是,那么bash脚本应该停止并echo一条消息。

因此,在上面的示例中,脚本应该停止,因为File2.txt不包含以下Q:LOAD_INVENTORY_Q

file1.txt或file2.txt中的Qs不遵循任何特定顺序。

5 个答案:

答案 0 :(得分:2)

以下命令将打印出file1.txt中的行,其值(=之后出现的任何内容)未出现在file2.txt中。

[me@home]$ awk -F= 'FNR==NR{keys[$0];next};!($2 in keys)' file2.txt file1.txt
dbipAddress=192.168.175.130
QLOAD_INVENTORY_Q=LOAD_INVENTORY_Q

命令细分:

awk -F= 'FNR==NR{keys[$0];next};!($2 in keys)' file2.txt file1.txt
    ---  ---------------------- -------------
     |           |                    |
change the       |               Target lines in file1.txt where
delimiter        |               the second column (delimited by `=`) do
  to '='         |               not exist in the keys[] array.
           Store each line in    
           file2.txt as a key
           in the keys[] array

要做更精细的事情,比如说如果您希望在继续编写脚本之前将命令作为预过滤器运行以确保文件有效,您可以使用:

awk -F= 'FNR==NR{K[$0];N++;next};!($2 in K) {print "Line "(NR-N)": "$0; E++};END{exit E}' file2.txt file1.txt
ERRS=$?
if [ $ERRS -ne 0 ]; then  
    # errors found, do something ...
fi

这将打印出不符合账单的file1.txt中的所有行(包括行号),并返回与不符合行数匹配的退出代码。这样,您的脚本可以通过选中$?并相应地做出响应来轻松检测错误。

示例输出:

[me@home]$ awk -F= 'FNR==NR{K[$0];N++;next};!($2 in K) {print "Line "(NR-N)": "$0;E++};END{exit E}' file2.txt file1.txt
Line 1: dbipAddress=192.168.175.130
Line 5: QLOAD_INVENTORY_Q=LOAD_INVENTORY_Q
[me@home]$ echo $?
2

答案 1 :(得分:1)

您可以使用cut仅获取=之后的部分。 comm可用于输出第一个文件中包含的行,但不能输出第二个文件中包含的行:

grep ^Q File1.txt | cut -d= -f2- | sort | comm -23 - <(sort File2.txt)

答案 2 :(得分:0)

以下命令行表达式将过滤掉file2.txt但不是file1.txt中出现的行:

cat file1.txt | grep -Fvf file2.txt | grep '^Q'

说明:

-F : match patterns exactly (no expansion etc.) ; much faster
-v : only print lines that don't match
-f : get your patterns from the file specified

| grep '^Q' : pipe the output into grep, and look for lines that start with "Q"

这并不完全是“当...时停止bash脚本”,因为它将处理和打印每个不匹配;此外,它没有测试模式前面是否有“=” - 但我希望它有用。

答案 3 :(得分:0)

假设file1.txt中的相关行始终以Q开头:

grep "^Q" file1.txt | while IFS= read -r line
do
    what=${line#*=}
    grep -Fxq "$what" file2.txt || echo "error: $what not found"
done

输出:

error: LOAD_INVENTORY_Q not found

答案 4 :(得分:0)

这是另一种方式:

missing=($(comm -23 <(awk -F= '/^Q/ {print $2}' file1.txt | sort) <(sort file2.txt)))
if (( ${#missing[@]} )); then
  echo >&2 "The following items are missing from file2.txt:"
  printf '%s\n' "${missing[@]}"
  exit 1
fi