显示该行的不常见部分

时间:2014-05-30 06:37:23

标签: linux bash

您好我有两个包含路径的文件。我想比较这两个文件并仅显示该行的不常见部分。

的1.txt:

/home/folder_name/abc

2.txt:

/home/folder_name/abc/pqr/xyz/mnp

我想要的输出:

/pqr/xyz/mnp

我该怎么做?

5 个答案:

答案 0 :(得分:1)

这一点awk完成了这项工作:

$ awk 'NR==FNR {a[++i]=$0; next}
{
    b[++j]=$0; 
    if(length(a[j])>length(b[j])) {t=a[j]; a[j]=b[j]; b[j]=t}
    sub(a[j],"",b[j]);
    print b[j]
}' 2.txt 1.txt  # or 2.txt 1.txt, it doesn't matter
  • 将第一个文件中的行写入数组a
  • 将第二行写入b
  • 如果a[j]超过b[j],则交换a[j]b[j](如果较长的文字始终位于b,则可能不需要这样做)。
  • a[j]移除b[j]中找到的部分并打印b[j]

这是一般解决方案;它没有假设匹配位于行的开头,或者一个文件的行的内容应该从另一个文件中移除。如果你能够做出这些假设,可以简化脚本。

如果匹配可能会多次出现,您可以使用gsub而不是sub来执行全局替换。

答案 1 :(得分:0)

此脚本将比较文件中的所有行,并仅输出行中的更改 首先,它计算第一个文件中的行数。

然后我开始一个循环,它将迭代行数 声明两个文件中同一行的两个变量 比较线条,如果它们是相同的输出。
如果它们没有,则用任何东西替换字符串的重复部分(有效地删除它们)
我使用:作为sed中的分隔符,因为您的变量包含/。因此,如果它们包含:,那么您可能需要考虑更改它们。

可能不是最有效的解决方案,但它有效。

#!/bin/bash

NUMOFLINES=$(wc -l < "1.txt")
echo $NUMOFLINES

for ((i = 1 ; i <= $NUMOFLINES ; i++)); do

f1=$(sed -n $i'p' 1.txt)
f2=$(sed -n $i'p' 2.txt)

if [[ $f1 < $f2 ]]; then
        echo -n "Line $i:"
        sed 's:'"$f1"'::' <<< "$f2"
elif  [[ $f1 > $f2 ]]; then
        echo -n "Line $i:"
        sed 's:'"$f2"'::' <<< "$f1"
else
        echo "Line $i: Both lines are the same"
fi

echo ""

done

答案 2 :(得分:0)

考虑到1.txt2.txt以下代码中的字符串可以使用。

paste 1.txt 2.txt | 
while read a b; 
do 
    if [[ ${#a} -gt ${#b} ]];
    then
        echo ${a/$b}; 
    else
        echo ${b/$a};
    fi;
done;

这就是我的系统的工作方式,

shiplu@:~/test/bash$ cat 1.txt 
/home/shiplu/test/bash
/home/shiplu/test/bash/hello/world
shiplu@:~/test/bash$ cat 2.txt 
/home/shiplu/test/bash/good/world
/home/shiplu/test/bash
shiplu@:~/test/bash$ paste 1.txt 2.txt | 
> while read a b; 
> do 
>     if [[ ${#a} -gt ${#b} ]];
>     then
>         echo ${a/$b}; 
>     else
>         echo ${b/$a};
>     fi;
> done;
/good/world
/hello/world

答案 3 :(得分:0)

如果您碰巧使用bash,可以试试这个:

echo $(diff <(grep -o . 1.txt) <(grep -o . 2.txt) \
| sed -n '/^[<>]/ {s/^..//;p}' | tr -d '\n')

它使用diff进行逐个字符的比较(其中grep -o .为每个字符提供一条中间线,以便输入到行式差异),然后打印差异(中间差异)输出行以标记<>省略,然后用tr连接行。

如果您的输入中有多行(您在问题中未提及),请尝试这样的操作(其中%是输入中未包含的字符):

diff <(cat 1.txt | tr '\n' '%' | grep -o .) \
 <(cat 2.txt | tr '\n' '%' | sed -e 's/%/%%/g' | grep -o .) \
| sed -n '/^[<>]/ {s/^..//;p}' | tr -d '\n' | tr '%' '\n'

这通过添加行结束标记(例如%)来扩展单行解决方案,通过在左侧添加%和在右侧添加%%,强制diff包含在其输出中。

答案 4 :(得分:0)

如果两个文件中的每个文件始终都有一行,则下面有效:

perl -lne '$a=$_ if($.==1);print $1 if(/$a(.*)/ && $.==2)' 1.txt 2.txt

下面测试:

> cat 1.txt
/home/folder_name/abc
> cat 2.txt
/home/folder_name/abc/pqr/xyz/mnp
> perl -lne '$a=$_ if($.==1);print $1 if(/$a(.*)/ && $.==2)' 1.txt 2.txt
/pqr/xyz/mnp
>