この質問は以下に関連しています。これそしてこれ質問。複数行を含むファイルがあり、各行はファイルへのパスです。今、各行を各行とペアリングしたいと思います。その他ライン(自体ではない)。また、私の目的に応じて、ペアはペアとA B
同じでB A
あるため、これらの組み合わせの1つだけを作成する必要があります。
はい
files.dat
短縮表記では、次のように読みます。各文字はファイルパス(絶対または相対)です。
a
b
c
d
e
それから私の結果は次のようになります。
a b
a c
a d
a e
b c
b d
b e
c d
c e
d e
bashでこの問題を解決することをお勧めします。他の質問とは異なり、私のファイルリストはかなり小さく(約200行)、ループとRAM容量を使用しても問題は発生しません。
答え1
次のコマンドを使用します。
awk '{ name[$1]++ }
END { PROCINFO["sorted_in"] = "@ind_str_asc"
for (v1 in name) for (v2 in name) if (v1 < v2) print v1, v2 }
' files.dat
PROCINFO
拡張かもしれませんgawk
。サポートされていない場合は、その行をawk
省略しPROCINFO["sorted_in"] = "@ind_str_asc"
て出力をパイプで接続しますsort
(出力をソートしたい場合)。
(これは本当ですいいえ入力をソートする必要があります。 )
答え2
すでにruby
インストールしている場合:
$ ruby -0777 -F'\n' -lane '$F.combination(2) { |c| puts c.join(" ")}' ip.txt
a b
a c
a d
a e
b c
b d
b e
c d
c e
d e
-0777
フルファイルをフルルックにしてください(OPでファイルサイズが小さいと言ったので大丈夫でしょう)。-F'\n'
$F
改行に基づいて分割され、各行が配列の要素になります。$F.combination(2)
2
結合要素を一度に生成{ |c| puts c.join(" ")}
リクエストに応じて印刷- 入力ファイルに重複項目が含まれる場合は、次のようにします。
$F.uniq.combination(2)
一度に3つの要素:
$ ruby -0777 -F'\n' -lane '$F.combination(3) { |c| puts c.join(" ")}' ip.txt
a b c
a b d
a b e
a c d
a c e
a d e
b c d
b c e
b d e
c d e
AND perl
(非ユニバーサル)
$ perl -0777 -F'\n' -lane 'for $i (0..$#F) {
for $j ($i+1..$#F) {
print "$F[$i] $F[$j]\n" } }' ip.txt
a b
a c
a d
a e
b c
b d
b e
c d
c e
d e
そしてawk
$ awk '{ a[NR]=$0 }
END{ for(i=1;i<=NR;i++)
for(j=i+1;j<=NR;j++)
print a[i], a[j] }' ip.txt
a b
a c
a d
a e
b c
b d
b e
c d
c e
d e
答え3
$ join -j 2 -o 1.1,2.1 file file | awk '!seen[$1,$2]++ && !seen[$2,$1]++'
a b
a c
a d
a e
b c
b d
b e
c d
c e
d e
これは、入力ファイルの行にスペースが含まれていないと仮定します。また、ファイルソート済み。
このjoin
コマンドは、ファイル内の行の完全な外積を生成します。存在しないフィールドでファイル自体をリンクしてこれを行います。非標準は-j 2
で置き換えることができます(ただし、GNUを使用しないと-1 2 -2 2
置き換えることはできません)。-j2
join
コマンドawk
はこの結果を読み取り、まだ確認されていないペアの結果のみを出力します。
答え4
これは純粋な殻です。
test $# -gt 1 || exit
a=$1
shift
for f in "$@"
do
echo $a $f
done
exec /bin/sh $0 "$@"
例:
~ (137) $ sh test.sh $(cat file.dat)
a b
a c
a d
a e
b c
b d
b e
c d
c e
d e
~ (138) $