シェルスクリプトの2つのファイルで一致するデータを見つけ、シェルの他のファイルに保存されている重複データを見つける方法は?
#!/bin/bash
file1="/home/vekomy/santhosh/bigfiles.txt"
file2="/home/vekomy/santhosh/bigfile2.txt"
while read -r $file1; do
while read -r $file2 ;do
if [$file1==$file2] ; then
echo "two files are same"
else
echo "two files content different"
fi
done
done
コードを書きましたが、うまくいきませんでした。どのように書くのですか?
答え1
両方のファイルが同じであることをテストするには、次のようにしますcmp -s
。
#!/bin/bash
file1="/home/vekomy/santhosh/bigfiles.txt"
file2="/home/vekomy/santhosh/bigfile2.txt"
if cmp -s "$file1" "$file2"; then
printf 'The file "%s" is the same as "%s"\n' "$file1" "$file2"
else
printf 'The file "%s" is different from "%s"\n' "$file1" "$file2"
fi
ユーティリティを「サイレント」にする-s
フラグを指定します。cmp
2つの同じファイルを比較すると、終了ステータスはcmp
0になります。上記のコードでは、両方のファイルが同じかどうかに関するメッセージを印刷するために使用されます。
2つの入力ファイルがある場合パス名のリストが含まれています。比較するファイルを選択し、次の二重ループを使用します。
#!/bin/bash
filelist1="/home/vekomy/santhosh/bigfiles.txt"
filelist2="/home/vekomy/santhosh/bigfile2.txt"
mapfile -t files1 <"$filelist1"
while IFS= read -r file2; do
for file1 in "${files1[@]}"; do
if cmp -s "$file1" "$file2"; then
printf 'The file "%s" is the same as "%s"\n' "$file1" "$file2"
fi
done
done <"$filelist2" | tee file-comparison.out
ここで結果は端末とファイルの両方で生成されますfile-comparison.out
。
両方の入力ファイルのパス名に改行文字が含まれていないとします。
files1
コードは、ファイルの1つのすべてのパス名を配列として読み取ることから始まりますmapfile
。他のファイルの各パス名のすべてのパス名を繰り返す必要があるため、ファイルを何度も読み取らないようにします。$filelist1
内部ループから読み取るのではなく、配列の名前を繰り返していることがわかりますfiles1
。
答え2
最も簡単な方法はコマンドを使用することですdiff
。
例:
file1.txt
最初のファイルが次のようになっているとします。
I need to buy apples.
I need to run the laundry.
I need to wash the dog.
I need to get the car detailed.`
そして2番目のファイルfile2.txt
I need to buy apples.
I need to do the laundry.
I need to wash the car.
I need to get the dog detailed.
その後、diffを使用して、2つのファイル間でどの行が異なるかを自動的に表示できます。コマンドは次のとおりです。
diff file1.txt file2.txt
出力は次のとおりです。
2,4c2,4
< I need to run the laundry.
< I need to wash the dog.
< I need to get the car detailed.
---
> I need to do the laundry
> I need to wash the car.
> I need to get the dog detailed.
この出力が何を意味するのか見てみましょう。覚えておくべき重要な点は、diffがこれらの違いを説明するときに指定されたコンテキスト内で説明することです。つまり、最初のファイルを2番目のファイルと一致するように変更する方法を教えてくれます。 diff 出力の最初の行には以下が含まれます。
- 最初のファイルの行番号に対応します。
- 文字(aは追加、cは変更、dは削除)
- 2番目のファイルに対応する行番号。
上記の出力では、「2,4c2,4」意味: 「ライン2渡す4最初のファイルの内容をその行と一致するように変更する必要があります。2渡す42番目のファイルに。その後、各ファイルの次の行の内容をお知らせします。
- < 先頭の行は最初のファイルの行です。
- >前の行は2番目のファイルの行です。
- 3 つのダッシュ ("---") は file1 と file2 の行のみを区切ります。
答え3
以下はファイル比較のための純粋なbashシェルスクリプトです:
#!/usr/bin/env bash
# @(#) s1 Demonstrate rudimentary diff using shell only.
# Infrastructure details, environment, debug commands for forum posts.
# Uncomment export command to run as external user: not context, pass-fail.
# export PATH="/usr/local/bin:/usr/bin:/bin"
set +o nounset
LC_ALL=C ; LANG=C ; export LC_ALL LANG
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
db() { : ; }
C=$HOME/bin/context && [ -f "$C" ] && $C
set -o nounset
FILE1=${1-data1}
shift
FILE2=${1-data2}
# Display samples of data files.
pl " Data files:"
head "$FILE1" "$FILE2"
# Set file descriptors.
exec 3<"$FILE1"
exec 4<"$FILE2"
# Code based on:
# http://www.linuxjournal.com/content/reading-multiple-files-bash
# Section 2, solution.
pl " Results:"
eof1=0
eof2=0
count1=0
count2=0
while [[ $eof1 -eq 0 || $eof2 -eq 0 ]]
do
if read a <&3; then
let count1++
# printf "%s, line %d: %s\n" $FILE1 $count1 "$a"
else
eof1=1
fi
if read b <&4; then
let count2++
# printf "%s, line %d: %s\n" $FILE2 $count2 "$b"
else
eof2=1
fi
if [ "$a" != "$b" ]
then
echo " File $FILE1 and $FILE2 differ at lines $count1, $count2:"
pe "$a"
pe "$b"
# exit 1
fi
done
exit 0
生産:
$ ./s1
Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64
Distribution : Debian 8.9 (jessie)
bash GNU bash 4.3.30
-----
Data files:
==> data1 <==
I need to buy apples.
I need to run the laundry.
I need to wash the dog.
I need to get the car detailed.
==> data2 <==
I need to buy apples.
I need to do the laundry.
I need to wash the car.
I need to get the dog detailed.
-----
Results:
File data1 and data2 differ at lines 2, 2:
I need to run the laundry.
I need to do the laundry.
File data1 and data2 differ at lines 3, 3:
I need to wash the dog.
I need to wash the car.
File data1 and data2 differ at lines 4, 4:
I need to get the car detailed.
I need to get the dog detailed.
読み取ったすべての行を表示するには、特定のコマンドのコメントを外して、最初の違いを見るとそのコマンドを終了させることができます。
ページを見るhttp://www.linuxjournal.com/content/reading-multiple-files-bashファイル記述子の詳細(例:「&3」)
頑張って...乾杯、drl