異なるファイル内のペアの単語のすべての可能な置換

異なるファイル内のペアの単語のすべての可能な置換

file1、file2など、いくつかのファイルがあります。各ファイルには1行に1単語があります。たとえば、次のようになります。

file1 file2 file3
one   four  six
two   five
three

私が望むのは、すべての可能な順列(繰り返しなし)で新しいファイル4にペアで結合することです。良い

onetwo
onethree
onefour
onefive
...
twothree
...
onefour
...
fourone
...

Linuxコマンドを使用してこれはどのように可能ですか?

答え1

Rubyはこの種の仕事に適した簡潔な言語です。

ruby -e '
  words = ARGV.collect {|fname| File.readlines(fname)}.flatten.map(&:chomp)
  words.combination(2).each {|pair| puts pair.join("")}
' file[123] > file4
onetwo
onethree
onefour
onefive
onesix
twothree
twofour
twofive
twosix
threefour
threefive
threesix
fourfive
foursix
fivesix

そうですね。combination"onetwo"が提供されましたが、"twoone"がありません。良いものがあります。permutation

ruby -e '
  words = ARGV.collect {|fname| File.readlines(fname)}.flatten.map(&:chomp)
  words.permutation(2).each {|pair| puts pair.join("")}
' file{1,2,3}
onetwo
onethree
onefour
onefive
onesix
twoone
twothree
twofour
twofive
twosix
threeone
threetwo
threefour
threefive
threesix
fourone
fourtwo
fourthree
fourfive
foursix
fiveone
fivetwo
fivethree
fivefour
fivesix
sixone
sixtwo
sixthree
sixfour
sixfive

答え2

入力ファイルの合計サイズがgetconf ARG_MAX(つまり、最大コマンドライン長)より小さいと仮定すると、次のように動作します。

set -- $( cat file[123] )
for f in $@ ; do
    for g in $@ ; do
        [ "$f" != "$g" ] && echo $f$g
    done
done > file4

cat file4出力:

onetwo
onethree
onefour
onefive
onesix
twoone
twothree
twofour
twofive
twosix
threeone
threetwo
threefour
threefive
threesix
fourone
fourtwo
fourthree
fourfive
foursix
fiveone
fivetwo
fivethree
fivefour
fivesix
sixone
sixtwo
sixthree
sixfour
sixfive

(OPの説明によると、上記の内容は正確です。繰り返されない配列。前のドラフトを見る 繰り返さない組み合わせ.)

答え3

一方python通行:

import fileinput
from itertools import permutations
from contextlib import closing
with closing(fileinput.input(['file1', 'file2', 'file3'])) as f:
    for x, y in permutations(f, 2):
            print '{}{}'.format(x.rstrip('\n'), y.rstrip('\n'))

onetwo
onethree
onefour
onefive
onesix
twoone
twothree
twofour
twofive
twosix
threeone
threetwo
threefour
threefive
threesix
fourone
fourtwo
fourthree
fourfive
foursix
fiveone
fivetwo
fivethree
fivefour
fivesix
sixone
sixtwo
sixthree
sixfour
sixfive

答え4

TXR リース:

ウォームアップ:まずデータ構造を取得します。

$ txr -p '(comb (get-lines (open-files *args*)) 2)' file1 file2 file3
(("one" "two") ("one" "three") ("one" "four") ("one" "five") ("one" "six")
 ("two" "three") ("two" "four") ("two" "five") ("two" "six") ("three" "four")
 ("three" "five") ("three" "six") ("four" "five") ("four" "six")
 ("five" "six"))

今、出力フォーマットを正しく設定することが問題です。ペアを一緒に接続してからtprint(暗黙的にoptionsを介して-t)使用すると、問題が解決します。

まず、マッピングを介して接続しますcat-str

$ txr -p '[mapcar cat-str (comb (get-lines (open-files *args*)) 2)]' file1 file2 file3
("onetwo" "onethree" "onefour" "onefive" "onesix" "twothree" "twofour"
 "twofive" "twosix" "threefour" "threefive" "threesix" "fourfive"
 "foursix" "fivesix")

いいですね。正しいデータがあります。ここで()の代わりに()tprint関数を使用してください。-tprinl-p

$ txr -t '[mapcar cat-str (comb (get-lines (open-files *args*)) 2)]' file1 file2 file3
onetwo
onethree
onefour
onefive
onesix
twothree
twofour
twofive
twosix
threefour
threefive
threesix
fourfive
foursix
fivesix

最後に、質問をもう一度読み、次のものと組み合わせるのではなく、必要に応じて配置しますpermcomb

$ txr -t '[mapcar cat-str (perm (get-lines (open-files *args*)) 2)]' file1 file2 file3
onetwo
onethree
onefour
onefive
onesix
twoone
twothree
twofour
twofive
twosix
threeone
threetwo
threefour
threefive
threesix
fourone
fourtwo
fourthree
fourfive
foursix
fiveone
fivetwo
fivethree
fivefour
fivesix
sixone
sixtwo
sixthree
sixfour
sixfive

関連情報