다음과 같은 파일이 있습니다.
1
2
3
# always a double newline
a
b
c # each subgroup has the same number of rows
9
10
y
z
...
기본적으로 열 1, 이중 개행, 열 2, 이중 개행, 다시 열 1
값의 성격(무엇이든 될 수 있음) 또는 "열"의 수(미리 알려져 있지만 2 또는 3일 수 있음)에 대해 가정하지 마십시오.
다음과 같은 출력이 나올 것으로 예상됩니다.
1,a
2,b
3,c
9,y
10,z
...
작업에 적합한 도구는 무엇입니까?
답변1
awk
및를 사용하는 또 다른 솔루션은 다음과 bash
같습니다.
paste -d, <(awk -v RS='\n\n' 'NR%2' file) <(awk -v RS='\n\n' '!(NR%2)' file)
이는 빈 줄만 구분 기호로 간주하며, 비어 있지 않은 줄은 무엇이든 될 수 있습니다.
답변2
샘플 입력 파일을 사용한 빠른 솔루션(입력 데이터를 c2.txt라는 로컬 파일에 복사하여 붙여넣었습니다). 모든 조건에서 가능한 오류를 테스트하지는 않지만, 시도해 보고 결과가 만족스러운지 확인할 수 있습니다.
$ paste -d"," <(grep -E '[0-9]' c2.txt) <(grep -E '[a-z]' c2.txt)
1,a
2,b
3,c
9,y
10,z
실제로 동일한 파일을 두 번 grep합니다. 하나는 문자열용이고 다른 하나는 문자열을 붙여넣기 위한 것입니다.
답변3
단락 모드에서 awk를 사용하는 것은 어떻습니까? 각 홀수 레코드를 인덱스 배열로 분할한 다음 짝수 레코드의 다음 인덱스를 사용하여 반복합니다.
awk -vRS= -F'\n' '
NR%2 {split($0,a); next} {for (i=1;i<=NF;i++) print a[i],$i}
' OFS=, file
1,a
2,b
3,c
9,y
10,z
주어진 것과 같은 보다 일반적인 입력에는 개행 필드 구분 기호를 사용하는 것이 안전합니다.file2
foo
bar
baz bar
a
b
c
9
10
hello world
z
그 다음에
awk -vRS= -F'\n' '
NR%2 {split($0,a); next} {for (i=1;i<=NF;i++) print a[i],$i}
' OFS=, file2
foo,a
bar,b
baz bar,c
9,hello world
10,z
답변4
파이썬 2 스크립트
OP는 입력 값이 무엇이든 될 수 있고 이중 줄 바꿈만을 가이드로 사용하도록 요청했기 때문에논평, 다음은 steeldriver의 입력 파일을 사용하여 테스트된 스크립트의 대체 버전입니다(원본 버전은 이 답변의 편집 기록에서 찾을 수 있음).
#!/usr/bin/env python
from __future__ import print_function
import sys
columns = []
counter = 0
def print_columns(cols):
half = len(cols)/2
print("\n".join([ x+","+y for x,y in zip(cols[0:half],cols[half:]) ]))
with open(sys.argv[1]) as fd:
for line in fd:
if line.strip() == '':
counter+=1
continue
if counter >0 and counter%4 == 0:
print_columns(columns)
columns = []
counter = 0
columns.append(line.strip())
print_columns(columns)
테스트 실행:
$ cat input.txt
foo
bar
baz bar
a
b
c
9
10
hello world
z
$ ./columnate_file.py input.txt
foo,a
bar,b
baz bar,c
9,hello world
10,z