比较两个或多个文件并仅打印第一个文件中包含第二个文件中不存在的单词的那些行

时间:2013-11-04 23:09:32

标签: regex bash shell sed awk

我在bash / sed / awk(有用的单行脚本)中尝试解决以下问题。

比较两个或多个文件,并仅打印第一个文件中包含同一名称中不存在于第二个文件中的单词(模式)的那些行,保留它们出现的顺序并忽略区分大小写。 (天哪,听起来如此复杂和愚蠢......我不知道如何用另一种方式说出来。)

我有两个不同的文件(file1,file2),其中包含以下信息列表:

文件1

Agents In The Court / No Love For The Empire
Mercenary Armor
Solo Han WB
Obi-Wan's Journal
Obi-Wan's Lightsaber
No Questions Asked
Do, or do Not
Strike Blocked

file2的

Agents In The Court / No Love For The Empire BB -> (LiGHT SIDE -- Special Cards)    
Mercenary Armor BB -> (LiGHT SIDE -- Device)
Obi-Wan's Journal BB -> (LiGHT SIDE -- Device)
No Questions Asked BB -> (LiGHT SIDE -- Special Cards)
Do, Or Do Not BB -> (LiGHT SIDE -- Defensive Shield)
Strike Planning BB -> (LiGHT SIDE -- Effect)
Alter (Obi-Wan) WB -> (LiGHT SIDE -- Used Interrupt)
Solo Han BB -> (LiGHT SIDE -- Human and Human-Like Characters)
Combined Attack BB -> (LiGHT SIDE -- Lost Interrupt)

结果应该是这样的:

Solo Han WB
Obi-Wan's Lightsaber
Strike Blocked

我将不胜感激任何帮助(完整的解决方案,提示,类似问题的链接等)。

4 个答案:

答案 0 :(得分:0)

我认为不存在单行;你可能会有一些临时文件。想法:

# just some boilerplate for handling temp files
t=`mktemp -d -t sort.XXXXXX`
trap "rm -rf $t" EXIT

# add two columns: file-id + line and sort by 3rd field (real data)
nl -ba -nln < file1 | sed -e 's/^/1 /' | sort -k3 >$t/file1
nl -ba -nln < file2 | sed -e 's/^/1 /' | sort -k3 >$t/file2

# get unique lines, filter these from file1, sort by line and give out data
uniq -f 2 $t/file1 $t/file2 | sort -n | cut -d ' ' -f 3-

(未经测试;可能需要对字段分隔符进行一些修复。)

上面的脚本需要比sed + gawk更多的工具,但是应该适用于最近的GNU系统。

答案 1 :(得分:0)

只要file2不是太大,其中任何一个都可以在bash中使用:

while read x; do if [[ -z "$(grep -Fi "$x" file2)" ]]; then echo "$x"; fi; done < file1

cat file1 | while read x; do if [[ -z "$(grep -Fi "$x" file2)" ]]; then echo "$x"; fi; done

总的来说,读取file1中的每一行,并在file2中读取grep,只有在找不到匹配项时才打印该行。

更详细地说,while read x; do ...; done < file1一次从file1读取一行到变量x。 "$(grep -Fi "$x" file2)"在包含$x内容的行中搜索file2,在找不到匹配项时评估为空字符串。 -F标志告诉grep搜索固定字符串,因此它不会将$x的内容视为正则表达式。 -i标志表示在搜索时忽略大小写。如果字符串参数为空(即grep找不到匹配项),则测试-z的计算结果为true。

答案 2 :(得分:0)

适合您需要的简单内容是内置差异

diff file1 file2

将打印出两个文件之间不同的所有行

答案 3 :(得分:0)

您也可以尝试:

awk -f print.awk file1

其中print.awk

BEGIN {
    while (getline < "file2")
        line[i++]=toupper($0)
}

{
    for (j=0; j<i; j++) {
        if (index(line[j],toupper($0))) { 
            f=1; break
        }
    }
    if (!f) print
    f=0
}