交差点を見つけるための簡単なスクリプトを作成したいと思います。複数のファイル(すべてのファイルの共通行)、したがって一部の項目を読んだ後(協会)bashスクリプトを作成しようとしましたが、残念ながら失敗しました。私は何が間違っていましたか?
RES=$(comm -12 ${1} ${2})
for FILE in ${@:3}
do
RES=$(comm -12 $FILE ${RES})
done
parallel
またはを使用してこれを達成する方法に関する他の提案はありますかxargs
?
答え1
関数は再帰的な方法を受け入れます。
f() {
if (($# == 1))
then
cat $1;
return;
fi
comm -12 $1 <(f "${@:2}")
}
f file1 file2 file3 file4 file5...
答え2
逆参照するときRES
:
comm $FILE ${RES}
content RES
replacement ${RES}
。ただし、引数としてファイルcomm
名が必要です。たとえば、$RES
含まれています。hello
comm
hello
代わりに、一時ファイルを使用してプロシージャ内に共通の行を保存できます。
tmp=$(mktemp --tmpdir)
tmp2=$(mktemp --tmpdir)
comm -12 ${1} ${2} >$tmp
for FILE in ${@:3}
do
comm -12 $FILE $tmp >$tmp2
rm $tmp
mv $tmp2 $tmp
done
cat $tmp
rm $tmp
答え3
いいえparallel
、必要xargs
ありませんcomm
。機能を試してください
$ intersection() { sort $@ | uniq -c | sed -n "s/^ *$# //p"; }
$ intersection file[1-3]
line2
line4
答え4
問題は、comm
2つのファイルが必要であり、$RES
変数であることです。
しかし、私たちはできます。だまされるそして、プロセス置換を使用してファイルのように見えます。
#!/bin/bash
RES=$(comm -12 ${1} ${2})
for FILE in ${@:3}
do
RES="$(comm -12 $FILE <(printf %s "${RES}"))"
done
printf %s "$RES"
ご覧のとおり、ソースとほぼ同じですが、構造を使用して<(...)
コマンドを実行し、それをファイル名として使用しています。
したがって、次の3つのファイルがある場合:
a:line1
a:line2
a:line3
a:line4
b:line2
b:line4
b:line6
c:line2
c:line4
c:line8
私たちはそれらを比較できます:
% ./allcomp a b c
line2
line4