Bash - 파일의 각 줄을 페어링합니다.

Bash - 파일의 각 줄을 페어링합니다.

이 질문은 다음과 관련이 있습니다.이것그리고이것질문. 여러 줄이 포함된 파일이 있는데, 각 줄은 파일의 경로입니다. 이제 각 행을 각 행과 페어링하고 싶습니다.다른라인(자체가 아님). 또한 내 목적에 따라 쌍은 쌍 A B과 동일 B A하므로 이러한 조합 중 하나만 생성되어야 합니다.

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대체될 수 없습니다 ).-j2join

명령 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) $ 

관련 정보