名前は同じですが、内容が異なる2つのディレクトリでテキストファイルを見つけようとします。
以下は私のコードですが、ここでクラッシュし続けます。
cati=`ls $1 | cat $i`
catj=`ls $2 | cat $j`
など...
どうすれば修正できますか?
#!/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
find
以下は、およびを使用する別のオプションです。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
「新規ユーザー」を歓迎します!私の考えでは、ここで最大の問題は、ファイル全体をシェル変数にロードしようとすることです。まず、これはうまくいきません。第二に、ファイルをシェルに読み込むと、バックティックによる変更が原因で比較が正しく機能しません。最後に、ファイル内のすべてのスペースが原因でコードが破損します。しかし、これらすべての解決策があります! :)
戻り値を使用すると、diff
ファイルをシェルに完全に読み込む必要がなくなります。このように:
if diff $i $j; then
echo $j
fi
その他の提案:
- シェルで条件文を実行するには、overを使用することをお勧め
[[
します。乱雑なアイテムとうまく[
機能します[[
。 - 紛失物にはどんなものがありますか?
$i
または空の場合は$j
どうなりますか?これにより、シェルはその行でエラーを発生させます。"$i"
シェルを実行または強制して、欠落している変数の場所をスケジュールできます"$j"
。 - 住宅検査あなたのコードを読んでベストプラクティスを提案します。
- Googleのシェルスタイルガイド他にも多くの技術があります。