탭으로 구분된 파일의 두 열을 하나로 결합

탭으로 구분된 파일의 두 열을 하나로 결합

이 형식의 데이터를 탭으로 구분된 파일로 가져오는 방법을 알고 싶습니다.

A  red     green  
B  yellow  orange  
C  blue    purple  

그리고 grep, 붙여넣기, 잘라내기, cat 및 기타 명령을 사용하여 다음과 같이 변환합니다.

A red
B yellow
C Blue
A green
B orange
C purple

답변1

Cut과 유사하게 awk를 사용하여 수행할 수도 있습니다.

$ awk '{print $1,$2}' aa.txt && awk '{print $1,$3}' aa.txt
A red
B yellow
C blue
A green
B orange
C purple
# OR to send the output in a new file:
$ (awk '{print $1,$2}' aa.txt && awk '{print $1,$3}' aa.txt) >aaa.txt

차이점은 awk가 잘라내기보다 공백을 더 잘 처리한다는 것입니다. 이 기능은 각 줄의 필드가 여러 공백으로 구분된 경우 유용합니다.

예를 들어, 파일 행 A red= 1 공백으로 구분된 경우 제안된 잘라내기 솔루션도 성공하지만 행 = A red3 공백인 경우 절단은 실패하고 awk는 필드 1과 2 또는 필드 1과 3을 가져오는 데 성공합니다. .

업데이트:
댓글에서 제안한 대로(don_crissti 덕분에) 이는 순수 awk에서도 수행할 수 있습니다.

awk 'BEGIN{FS=OFS=" "}{z[NR]=$1FS$3; print $1,$2}END{for (i=1; i<=NR; i++){print z[i]}}' a.txt

설명하다:

FS           : Input Field Separator
OFS          : Output Field Separator
FS=OFS=" "   : input & output field separator is set to "space"
z[NR]        : Creating an array with name 'z' and index the record number: 
             z[1] for first line, z[2] for second line , z[3] for third line
z[NR]=$1FS$3 : to each array element assign field1-FieldSeparator FS=space)-field2
So for first line the fields1=A and Fields 3=green will be stored in z[1] => equals to z[1]="A green"

print $1,$2  : Justs prints on screen 1stfield (A) and 2ndfield (red) of the current line, printed separated by OFS

When the file is finished (END) then with a for loop we print out the whole z array entries => print z[i]
For i=1 => print z[1] => prints "A green"
For i=2 => print z[2] => prints "B orange"
For i=3 => print z[3] => prints "C purple"

PS: If fields are not separated by space but by tab , then Begin section of this awk one-liner must be changed to `awk 'BEGIN {FS=OFS="\t"}....`

답변2

cut파일에 쓰는 것이 마음에 들지 않으면(필요한 경우 원본 파일을 먼저 복사) 다음을 사용할 수 있습니다 .

$ cut -f 1,3 file >> file && cut -f 1,2 file
A   red
B   yellow
C   blue
A   green  
B   orange  
C   purple 

설명하다

  • cut -f 1,3 file첫 번째 및 세 번째 열을 인쇄합니다 file(대부분 탭으로 구분).
  • >> filefile터미널에 표시하는 대신 출력을 추가합니다.
  • &&작동하면 다음 명령을 실행하십시오.
  • cut -f 1,2 filefile터미널의 첫 번째와 두 번째 열만 인쇄합니다.

file자체는 다음과 같이 표시됩니다.

A   red     green  
B   yellow  orange  
C   blue    purple  
A   green  
B   orange  
C   purple  

따라서 원하는 최종 출력을 파일로 얻으려면 새 파일로 리디렉션해야 합니다.

cut -f 1,3 file >> file && cut -f 1,2 file > file2

답변3

Zanna의 솔루션과 유사하지만 중간 파일/결과가 없습니다.

$ ( cut -f1,2 data && cut -f1,3 data ) >data.new

서브쉘의 출력은 최종 파일에 저장됩니다 data.new. 서브셸은 먼저 처음 두 열을 추출한 다음 첫 번째와 세 번째 열을 추출합니다.

답변4

awk '{print 1 $1,$2; print 2 $1,$3}' ex |sort |cut -c 2-

업데이트: 주문이 유지되도록 하려면 다음을 수행하세요.

awk '{print 1,$1,$2; print 2,$1,$3}' ex |sort -sk1,1 |cut -c 3-
  • sort -sk1,1안정적인 첫 번째 필드 정렬

(\감사합니다 {Kusalananda})

관련 정보