如何查找文件名相同但内容不同的文件

如何查找文件名相同但内容不同的文件

我试图从两个不同的目录中查找具有相同名称但包含不同内容的文本文件。

以下是我的代码,但它一直在这里崩溃

cati=`ls $1 | cat $i`

catj=`ls $2 | cat $j` 

ETC...

我怎样才能纠正它?

#!/bin/bash

if [ $# -ne 2 ];then
    echo "Usage ./search.sh dir1 dir2"
    exit 1
elif [ ! -d  $1 ];then
    echo "Error cannot find dir1"
    exit 2
elif [ ! -d  $2 ];then
        echo "Error cannot find dir2"
        exit 2
elif [ $1 == $2 ];then
    echo "Error both are same directories"

else
    listing1=`ls $1`
    listing2=`ls $2`
    for i in $listing1; do
            for j in $listing2; do
                if [ $i == $j ];then
                     cati=`ls $1 | cat $i`
                     catj=`ls $2 | cat $j`
                     if [ $cati != $catj ];then
                           echo $j
                     fi
                fi

            done
    done
fi

答案1

这是另一个使用findand 的选项while read loop

#!/usr/bin/env bash

##: Set a trap to clean up temp files.
trap 'rm -rf "$tmpdir"' EXIT

##: Create temp directory using mktemp.
tmpdir=$(mktemp -d) || exit

##: If arguments less than 2
if (( $# < 2 )); then
  printf >&2 "Usage %s dir1 dir2 \n" "${BASH_SOURCE##*/}"
  exit 1
fi

dirA=$1
dirB=$2

##: Loop through the directories
for d in "$dirA" "$dirB"; do
  if  [[ ! -e $d ]]; then  ##: If directory does not exists
    printf >&2 "%s No such file or directory!\n" "$d"
    exit 1
  elif [[ ! -d $d ]]; then  ##: If it is not a directory.
    printf >&2 "%s is not a directory!\n" "$d"
    exit 1
  fi
done

##: If dir1 and dir2 has the same name.
if [[ $dirA = $dirB ]]; then
  printf >&2 "Dir %s and %s are the same directory!\n" "$dirA" "$dirB"
  exit 1
fi

##: Save the list of files in a file using find.
find "$dirA" -type f -print0 > "$tmpdir/$dirA.txt"
find "$dirB" -type f -print0 > "$tmpdir/$dirB.txt"


##: Although awk is best for comparing 2 files I'll leave that to the awk masters.

while IFS= read -ru "$fd" -d '' file1; do  ##: Loop through files of dirB
  while IFS= read -r -d '' file2; do ##: Loop through files of dirA
    if [[ ${file1##*/} = ${file2##*/} ]]; then  ##: If they have the same name
      if ! cmp -s "$file1" "$file2"; then ##: If content are not the same.
        printf 'file %s and %s has the same name but different content\n' "$file1" "$file2"
      else
        printf 'file %s and %s has the same name and same content\n' "$file1" "$file2"
      fi
    fi
  done < "$tmpdir/$dirA.txt"
done {fd}< "$tmpdir/$dirB.txt"

答案2

欢迎“新用户”!我认为这里的主要问题是尝试将整个文件加载到 shell 变量中。首先,这不会很好地扩展。其次,由于将文件读入 shell 时反引号所做的更改,比较效果不会很好。最后,文件中的所有空格都会破坏您的代码。但这一切都是有办法解决的! :)

您可以使用返回值diff并完全避免将文件读入 shell。就像这样:

if diff $i $j; then
     echo $j
fi

其他一些建议:

  • 在 shell 中使用[[over执行条件语句是个好主意。处理混乱的物品[效果[[更好。
  • 什么样的丢失物品​​?如果$i$j为空怎么办?然后 shell 会在该行出错。您可以通过执行"$i"或强制 shell 为缺失的变量保留一个位置"$j"
  • 外壳检查将阅读您的代码并提出最佳实践建议。
  • 谷歌的 shell 风格指南还有很多其他技巧。

相关内容