繁体   English   中英

如何在 shell 脚本中显示两个文件之间不同的前五行?

[英]How can i display the first five lines that differ between 2 files, in a shell script?

我试过使用 2 个数组来比较 2 个文件,但我是新手,我不知道该怎么做:

vec_fis_1=`cat fisier.txt`
vec_fis_2=`cat fisier1.txt`
echo $vec_fis_2
echo $vec_fis_1
for i in ${vec_fis_1[@]}
do
        for j in ${vec_fis_2[@]}
        do
                if ( "$i" == "$j" )
                then
                        echo $i
                        echo $j
                fi
        done
done

从你的问题中不清楚你到底想要什么:

  1. 您是否需要来自两个文件的 5 行不同的行
  2. 每个文件需要 5 行不同的行吗

下面的例子不是最新的解决方案,而是进一步思考的食物

第一种情况的解决方案 - 仅取差异并打印前 5 行:

comm -3 FILE1 FILE2 | head -n5

第二种情况的解决方案——仅取差异并从每个文件中打印 5 行不同的行(共 10 行):

comm -3 FILE1 FILE2 | head -n10

更新:

上面的示例是在FILE1FILE2都已排序的假设下提出的。 如果它们未排序,则需要按如下方式增强两个示例:

comm -3 <( sort FILE1 ) <( sort FILE2 ) | ...

笔记:

  1. 其余命令(管道后的省略号)是相同的。
  2. 这是 BASH 方式

不要使用反引号`。 使用$(..)代替。

所以代替if ( "$i" == "$j" ) if [ "$i" != "$j" ]

vec_fis_1vec_fis_2不是数组 - ${vec_fis_1[@]}$vec_fis_1相同。

要将文件读入数组,请使用readarray

要遍历文件中的行,请使用while read loop ,请参阅bashfaq 如何逐行读取文件

while IFS= read -r l1; do
     while IFS= read -r l2; do
         if [ "$l1" != "$l2" ]; then
            printf "%s\n" "$l1"
            printf "%s\n" "$l2"
         fi
     done < fisier1.txt
done < fisier.txt

我只需要具有相同“行索引”的行之间的差异

所以同时从两个文件中读取。

while IFS= read -r -u3 l1 && 
         IFS= read -r -u4 l2; do
    if [ "$l1" != "$l2" ]; then
        printf "%s\n" "$l1"
        printf "%s\n" "$l2"
     fi
done 3< fisier.txt 4< fisier1.txt

您也可以处理不同的行数。 我有这个(相当冗长)的想法:

while true; do

    IFS= read -r -u3 l1
    l1valid=$?
    IFS= read -r -u4 l2
    l2valid=$?
    if ((l1valid != 0 || l2valid != 0)); then
        if ((l1valid != 0 && l2valid == 0)); then
           echo "file1 is longer then file2"
        elif ((l1valid == 0 && l2valid != 0)); then
           echo "file1 is shorter then file2"
        fi # l1valid != 0 && l2valid != 0 - all fine
        break;
    fi

    if [ "$l1" != "$l2" ]; then
        printf "%s\n" "$l1"
        printf "%s\n" "$l2"
     fi

done 3< fisier.txt 4< fisier1.txt

或喜欢:

while
    IFS= read -r -u3 l1
    l1valid=$?
    IFS= read -r -u4 l2
    l2valid=$?
    if ((l1valid != 0 && l2valid == 0)); then
       echo "file1 is longer then file2"
    elif ((l1valid == 0 && l2valid != 0)); then
       echo "file1 is shorter then file2"
    fi
    (( l1valid == 0 && l2valid == 0 ))
do
    if [ "$l1" != "$l2" ]; then
        printf "%s\n" "$l1"
        printf "%s\n" "$l2"
     fi
done 3< fisier.txt 4< fisier1.txt

请注意,bash 循环非常慢,使用 awk 会快很多:

awk -vother="fisier1.txt" '{ t=$0; getline < (other); if (t != $0) print $0 RS t }' fisier.txt

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM