Linux 显示行中不常见的部分
嗨,我有两个包含路径的文件。我想比较这两个文件,只显示行中不常见的部分 1.txt:Linux 显示行中不常见的部分,linux,bash,Linux,Bash,嗨,我有两个包含路径的文件。我想比较这两个文件,只显示行中不常见的部分 1.txt: /home/folder_name/abc 2.txt: /home/folder_name/abc/pqr/xyz/mnp 我想要的输出: /pqr/xyz/mnp 我怎样才能做到这一点呢?这一点awk可以做到: $ awk 'NR==FNR {a[++i]=$0; next} { b[++j]=$0; if(length(a[j])>length(b[j])) {t=a[j];
/home/folder_name/abc
2.txt:
/home/folder_name/abc/pqr/xyz/mnp
我想要的输出:
/pqr/xyz/mnp
我怎样才能做到这一点呢?这一点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
- 从
中移除b[j]
中找到的零件,然后打印a[j]
b[j]
如果匹配可能在行中出现多次,则可以使用
gsub
而不是sub
执行全局替换。此脚本将比较文件中的所有行,并仅输出行中的更改。首先,它统计第一个文件中的行数 然后我开始一个循环,循环的行数。
声明两个文件中同一行的两个变量。
比较这些行,如果它们是相同的输出。
如果没有,则将字符串的重复部分替换为零(有效地删除它们)
我使用
:
作为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
#/bin/bash
NUMOFLINES=$(wc-l<“1.txt”)
echo$NUMOFLINES
对于((i=1;i考虑到您在1.txt
和2.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
如果您碰巧使用了bash,可以尝试以下方法:
echo $(diff <(grep -o . 1.txt) <(grep -o . 2.txt) \
| sed -n '/^[<>]/ {s/^..//;p}' | tr -d '\n')
这通过添加行结束标记(例如%)扩展了单行解决方案,diff通过在左侧添加%和在右侧添加%%强制将其包含在其输出中。如果两个文件中的每一行始终只有一行,则以下操作有效:
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
>
为什么不使用diff?你只需要不同的部分吗?一个总是另一个的前缀吗?1总是2的前缀吗?或者可以反过来吗?即使两个文件中的行相同,这仍然打印行吗?而且在一个有多行的文件中它似乎对我不起作用?@Jidder在回答你的第一个问题时,我不是这是一个要求。我已经对第二个问题进行了编辑。谢谢。第一个问题是,如果行相同,它仍在打印,用户会觉得这是它们之间的区别,不管怎样,您的编辑解决了这两个问题。做得好!不是bash!是perl!我用过,也不是,您用的是读取一个具有变量空间的B</代码>。由于使用粘贴,它会考虑第二个字,从<代码> a <代码>为<代码> b>代码>,b还包含应该在<代码> b <代码>中的数据。
> 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
>