단일 행을 3개 열의 여러 행으로 분할하는 방법이 있습니다. 파일의 모든 줄 끝에 개행 문자가 없습니다.
awk를 사용해 보았지만 행당 3개의 열 대신 각 열을 행으로 분할합니다.
awk '{ gsub(",", "\n") } 6' filename
내용 filename
은 다음과 같습니다.
A,B,C,D,E,F,G,H,I,J,K,L,M,N,O
원하는 출력에는 행당 3개의 열이 있습니다.
A,B,C
D,E,F
G,H,I
J,K,L
M,N,O
답변1
사용awk
$ awk -v RS='[,\n]' '{a=$0;getline b; getline c; print a,b,c}' OFS=, filename
A,B,C
D,E,F
G,H,I
J,K,L
M,N,O
어떻게 작동하나요?
-v RS='[,\n]'
이는 awk가 쉼표나 개행 문자를 레코드 구분 기호로 사용하도록 지시합니다.
a=$0; getline b; getline c
이는 awk에게 현재 줄을 변수에 저장
a
하고 다음 줄을 변수에 저장b
하고 다음 줄을 변수에 저장하도록 지시합니다c
.print a,b,c
이는 awk에게
a
,b
및 를 인쇄하라고 지시합니다.c
OFS=,
이는 awk에게 출력에서 필드 구분 기호로 쉼표를 사용하도록 지시합니다.
사용 tr
및paste
$ tr , '\n' <filename | paste -d, - - -
A,B,C
D,E,F
G,H,I
J,K,L
M,N,O
어떻게 작동하나요?
tr , '\n' <filename
쉼표를 개행 문자로 변환하는 동안 파일 이름에서 읽습니다.
paste -d, - - -
그러면 표준 입력에서
paste
세 줄(각각 한 줄)을 읽어서 함께 붙여넣습니다. 각 줄은 쉼표( )로 구분됩니다.-
-d,
awk의 대안
$ awk -v RS='[,\n]' '{printf "%s%s",$0,(NR%3?",":"\n")}' filename
A,B,C
D,E,F
G,H,I
J,K,L
M,N,O
어떻게 작동하나요?
-v RS='[,\n]'
이는 awk가 쉼표나 개행 문자를 레코드 구분 기호로 사용하도록 지시합니다.
printf "%s%s",$0,(NR%3?",":"\n")
NR
이는 awk에게 현재 줄을 인쇄하고, 현재 줄 번호 값( 모듈로 3) 에 따라 쉼표나 개행 문자가 뒤에 오도록 지시합니다 .
답변2
sed 's/\(\([^,]\+,\)\{3\}\)/\1\n/g;s/,\n/\n/g' filename
귀하가 해결책을 요청했다는 것을 알고 있습니다 awk
. 지금 이 답변에 대한 편집 내용으로 제출하려고 합니다. 그러나 저에게는 sed
해결책이 더 간단했습니다... 사용자 john1024가 멋진 솔루션으로 저를 이겼습니다 awk
. 저기 봐. 그의 paste
솔루션은 tr
아마도 가장 적절한 고전적인 UNIX 답변일 것입니다.
이 솔루션은 GNU sed의 확장 정규식 기능을 사용합니다.
\(..\)
정규식 컬렉션 그룹입니다. 이 솔루션은 두 개를 사용하는데, 하나는 다른 하나 안에 중첩되어 있습니다.[^,]+,
쉼표 뒤에 쉼표가 오는 문자열입니다. 귀하의 경우에는 열이나 필드입니다.\{3\}
이전 정규식을 세 번 사용하는 정규식 승수입니다.\1
정규식 역참조입니다. 이전 정규 표현식으로.g
라인의 모든 인스턴스에 대해 이 작업을 수행한다는 의미입니다.s/,\n/\n/g
후행 쉼표를 제거하세요.sed
입력은 여전히 한 줄로 처리되므로 여기에 개행 문자를 포함해야 합니다 .