쌍에서 쌍 파일 만들기

쌍에서 쌍 파일 만들기

다음과 같은 파일이 있다고 가정해 보겠습니다.

A 1
B 2
CC 33

다음과 같이 이전 파일의 두 가지 조합을 모두 포함하는 파일을 만들고 싶습니다.

AA 11
AB 12
ACC 133
BA 21
BB 22
BCC 233
CCA 331
CCB 332
CCCC 3333

임의의 파일에 대해 bash를 사용하여 이 작업을 수행할 수 있습니까? 각 항목에는 개행과 공백을 제외한 모든 문자가 포함될 수 있습니다. 일부 항목에는 UTF-8 문자가 포함됩니다.

나는 순서에 관심이 없습니다.

답변1

이 작업은 모두 셸에서 수행할 수 있습니다.

while read -r f1 f2
do
    while read -r f3 f4
    do
        printf "%s %s\n" "$f1$f3" "$f2$f4"
    done < your_file
done < your_file

IFS=" " read"각 항목에는 줄 바꿈과 공백을 제외한 모든 문자가 포함될 수 있습니다." 항목에 탭 문자가 포함될 수 있다는 의미라면 대신에 read(두 번) 이라고 말하세요 .

"세부":

이와 같은 명령은 read f1 f2 입력 줄의 첫 번째 "단어"를 변수로 f1 읽고나머지 줄입력하다 f2. 예를 들어, 입력은 sum 을 The quick brown fox 생성합니다 . 파일에 3개(또는 그 이상) 열이 포함되지 않을 것이라고 확신하는 경우(즉, 한 줄에 2개 이상의 단어가 포함되지 않음) 걱정할 필요가 없습니다. 첫 번째 단어의 일부가 아닌 모든 항목이 두 번째 단어의 일부로 간주된다는 점에 만족한다면 위 코드는 문제가 없을 것입니다. f1="The"f2="quick brown fox"

The quick brown fox그러나 처리 f1="The" 되어 f2="quick"무시 brown fox(무시) 되려면 read각 명령에 세 번째 변수를 추가하십시오. 예를 들어 ; f1 f2가 됩니다 . 그러면 , 및 f1 f2 x가 됩니다 . 그냥 사용하지 말고 두 번째 단어 이후의 입력을 삭제합니다. 두 번째도 마찬가지로 - 사용하지 않으므로 덮어써도 상관없습니다. 예를 들어 다른 일회성 변수를 사용하려는 경우 에도 가능합니다.f1="The"f2="quick"x="brown fox"$xreadread -r f3 f4 x$x… f3 f4 y

기본적으로 이 read명령은 백슬래시( \) 문자를 특별히 처리합니다. 기본적으로 백슬래시 뒤에 다른 문자가 오면 두 번째 문자의 특수 버전으로 병합됩니다. 그러나 더 중요한 것은 백슬래시 뒤에 공백이 오는 것은 단어 구분 기호로 간주되지 않으며, 백슬래시 뒤에 줄 바꿈(즉, 줄 끝의 백슬래시)은 줄 구분 기호/종료 기호로 간주되지 않는다는 것입니다 \C\C. CC. read이 옵션을 호출하면 -r옵션이 중지되고 백슬래시가 일반 문자가 됩니다. 다음은 차이점에 대한 몇 가지 실제적인 예입니다.

            -r 없음(기본값) __ -r 사용 __
_입력_ f1 f2 f1 f2
A\B\\C AB\CA\B\\C
D\EFDEFD\EF    (또는 f2="E" 및 x="F")
G\          (한 줄로 계산되지 않습니다.)        G\
GH GH

그래서 답변의 첫 번째 버전에 마크업을 추가했습니다 -r. 한 단어로 처리하고 싶다면 D\ E사용하지 마세요 -r.

답변2

awk파일을 두 번 읽어 볼 수 있습니다 .

awk 'NR == FNR { m[$1] = $2; next; } { for (i in m) { print $1 i, $2 m[i]; } }' file file

답변3

순서를 유지하고 파일을 두 번 읽는 것을 방지하려면 다음을 수행합니다.

awk '{f1[NR] = $1; f2[NR] = $2}
     END {
       for (i = 1; i <= NR; i++)
        for (j = 1; j <= NR; j++)
          print f1[i]f1[j], f2[i]f2[j]
     }' file

이제 전체 파일의 내용은 처리 전에 메모리에 저장됩니다(예:@taliezin의 접근 방식). 그렇게 하고 싶지 않다면 파일에 있는 줄 수만큼 파일을 읽어야 합니다.@G-Man의 방법. 그러나 / (awkshbash이것은 이것을 위해 설계되지 않았습니다)가 더 효율적일 것입니다.

 awk '{f1=$1; f2=$2
       while ((getline < "file") > 0) print f1$1, f2$2
       close("file")}' file

관련 정보