たとえば、ディレクトリにn個のファイルがあるとします。
a
b
c
これらのファイルの組み合わせ(非指定)を関数にどのように渡すことができますか?
予想される出力は次のとおりです。
a-b
a-c
b-c
このようにして、次の関数に渡すことができます。
fn -file1 a -file2 b
fn -file1 a -file2 c
...
これが私が今試していることです。
for i in *.txt
do
for j in *.txt
do
if [ "$i" != "$j" ]
then
echo "Pairs $i and $j"
fi
done
done
出力
Pairs a.txt and b.txt
Pairs a.txt and c.txt
Pairs b.txt and a.txt
Pairs b.txt and c.txt
Pairs c.txt and a.txt
Pairs c.txt and b.txt
私はまだ重複したファイルを持っていて(abはbaと同じです)、おそらくこれを行うより良い方法があると思いました。
答え1
ファイル名を配列に入れ、2つのループを介して手動で実行します。
次の場合は、1つの一致のみを取得できます。j <私どこ私そしてジェイ外部ループと内部ループでそれぞれ使用されるインデックスです。
$ touch a b c d
$ f=(*)
$ for ((i = 0; i < ${#f[@]}; i++)); do
for ((j = i + 1; j < ${#f[@]}; j++)); do
echo "${f[i]} - ${f[j]}";
done;
done
a - b
a - c
a - d
b - c
b - d
c - d
答え2
あなたのスクリプトは非常に似ていますが、重複したエントリを削除しようとしています。つまり、abはbaの重複エントリとして扱われます。
これを処理するために不平等を使用することができます。ファイル名は、最初のファイルが2番目のファイルよりもアルファベット順に前にある場合にのみ表示されます。これにより、ゲームごとに1つしか存在できません。
for i in *.txt
do
for j in *.txt
do
if [ "$i" \< "$j" ]
then
echo "Pairs $i and $j"
fi
done
done
これは出力を提供します
Pairs a.txt and b.txt
Pairs a.txt and c.txt
Pairs b.txt and c.txt
これは効率的なアルゴリズムではありませんが(O(n^2))、あなたのニーズには十分かもしれません。
答え3
空白のないファイル名のヒントjoin
:
ファイルの例のリスト:
$ ls *.json | head -4
1.json
2.json
comp.json
conf.json
$ join -j9999 -o1.1,2.1 <(ls *.json | head -4) <(ls *.json | head -4) | awk '$1 != $2'
1.json 2.json
1.json comp.json
1.json conf.json
2.json 1.json
2.json comp.json
2.json conf.json
comp.json 1.json
comp.json 2.json
comp.json conf.json
conf.json 1.json
conf.json 2.json
conf.json comp.json
-j
オプションは結合するパブリックフィールドの位置を指しますが、次のような-j9999
混合結合をトリガーします。デカルト製品。
答え4
Perlモジュールを使用すると、Alogithm::Combinatorics
アルゴリズムを直接設計することを回避できます。
perl -MAlgorithm::Combinatorics=combinations -e '
if ((@files = <*.txt>) >= 2) {
for (combinations(\@files, 2)) {
system "cmd", "-file1", $_->[0], "-file2", $_->[1];
}
} else {
die "Not enough txt files in the current working directory\n";
}'
perldoc Algorithm::Combinatorics
モジュールが実行できる詳細やその他の作業については、リソースを参照してください。