如何使用 sed 从一个文件中删除另一个文件中的相同行?

如何使用 sed 从一个文件中删除另一个文件中的相同行?

我有两个文件,一个是另一个的超集。我想从较大的文件中删除较小文件中的相同行。

一种可能的复杂情况是这些行包含反斜杠。

我该怎么做呢?

答案1

这是我的片段:

remove_lines()
{
    # remove lines from a file 
    #  
    # $1 - source file with patterns of lines to be removed
    # $2 - destination file
    tmpfile=$(mktemp "$(dirname -- "$2")"/XXXXXXXX) &&
    grep -F -f "$1" -v -- "$2" >>"$tmpfile" &&
    mv -- "$tmpfile" "$2" &&
}

编辑:我刚刚意识到其中没有sed,但这并不重要,不是吗?

答案2

@rajish 的答案grep很接近,但忽略了一些东西:关于删除相同内容的问题线。默认情况下,grep会匹配字符串(部分线条)。

POSIX grep有一个合适的选择:

-x
仅考虑使用行中除终止符之外的所有字符的输入行新队匹配整个固定字符串或正则表达式作为匹配行。

鉴于此,人们可以grep这样做:

cp -f -p input.txt input.txt~
grep -v -x -F -f input.pat input.txt~ >input.txt

在哪里输入.pat包含要删除的行,并且输入.txt是要更新的文件。

@nvarun 的解决方案使用 sed除了不转义/模式文件中的字符之外,还有类似的问题。这个例子对我有用,并将语法限制为POSIX sed:

cp -f -p input.txt input.txt~
sed -e 's/\([\/]\)/\\\1/g' -e 's/^/\/^/' -e 's/$/$\/d/' input.pat > input.sed
sed -f input.sed input.txt~ >input.txt

为了整洁起见,两者都在更新之前保存原始文件(POSIX cp)。

输入.pat

first
this is second
second/third
second\third

输入.txt

first
only first should match
this is not first
this is second
the previous line said this is second
first/second/third
second/third
first\second\third
second\third

结果:

only first should match
this is not first
the previous line said this is second
first/second/third
first\second\third

答案3

尝试以下脚本;

## $1 - Small File
## $2 - Large File

sed 's/^/\//; s/$/\/d/; s/\\/\\\\/g' $1 > $HOME/sed_scpt.txt
sed 's/\\/\\\\/g' $2 | sed -f $HOME/sed_scpt.txt > $HOME/desired_output.txt

## Alternatively, you could change the 2nd line with the following;
sed -f $HOME/sed_scpt.txt $2 > $HOME/desired_output.txt

注意:我使用过 GNU sed 4.2.1。

相关内容