다음과 같은 파일이 있다고 가정해 보겠습니다.
23: a, b, c, d
24: b, d, f
25: c, g
다음과 같은 출력을 얻고 싶습니다.
23.a
23.b
23.c
23.d
24.b
24.d
24.f
25.c
25.g
물론, 그냥 타이핑하는 것도 그리 어렵지는 않지만, awk와 같은 것을 사용하는 영리한 한 줄짜리 코드가 있는지 궁금합니다.
답변1
어쩌면 다음과 같은 것일 수도 있습니다.
sed 's/: /./;s/\(\([^.]*\.\)[^,]*\), /\1\
\2/;P;D'
\<LF>
이는 두 줄입니다( 일부 구현으로 대체 가능 ).\n
sed
이 D
명령은 구현하는 방법입니다.while 루프존재하다 sed
. 패턴 공간의 첫 번째 줄을 삭제하고 패턴 공간에 남아 있는 내용부터 다시 시작합니다. 따라서 위의 내용은 다음과 같이 이해될 수 있습니다.
do {
- change ": " to "." so we start with "23.a, b, c"
- change "23.x, y, z" to "23.x\n23.y, z"
- print the first line ("23.x"): P
- remove it
} while (pattern space is not empty)
첫 번째 명령이 루프의 일부가 될 필요는 없지만 이를 방지하려면 레이블( ) 및 분기 명령( , ) s
을 사용하는 등 보다 자세한 유형의 루프를 사용해야 합니다 .:
b
t
답변2
괜찮아요. 방금 이 작업을 매우 쉽게 만들어준 awk 분할 기능이 기억났어요.
awk -F ":" '{
split($2, ps, ",");
for (i in ps) {
gsub(" ", "",ps[i]);
print $1 "." ps[i];
}
}'
(gsub는 불필요한 공백을 제거하고 있습니다.)
그래도 다른 사람들의 답변에 감사드립니다.
답변3
여기 Perl이 있습니다:
perl -nle '/(.+?):\s*(.+)/; print "$1.$_" for split(/[,\s]+/,$2);' foo.txt
설명하다:
perl -nle
: 이는 Perl에게 입력 파일을 한 번에 한 줄씩 구문 분석하고(-n
), 인수로 제공된 스크립트를 실행하고,-e
인쇄된 각 문자열( )에 새 줄( )을 추가하도록 지시합니다.\n
-l
/(.+?):\s*(.+)/
: 첫 번째 문자와 첫 번째 콜론, 그 뒤에 0개 이상의 공백(:\s*
), 그 다음 줄의 나머지 부분까지 일치시킵니다. 괄호는 패턴 캡처를 위한 Perl 구문이며 두 개의 일치 항목이$1
합계 로 저장됩니다$2
.split(/[,\s]*/,$2);
: 이는 공백 및/또는 공백$2
(위 일치 작업의 두 번째 일치 패턴)에서 분할되어 익명 배열을 생성합니다.,
print "$1.$_" for split()
:위의 분할로 생성된 익명 배열을 반복하여 각 배열 구성원을 로 저장하고 (첫 번째 단계에서 캡처한 첫 번째 패턴) 및 점과$_
함께 인쇄합니다 .$1
.
답변4
나는 awk one-liner가 다른 awk 솔루션보다 더 우아하다고 생각합니다.
awk -F'[:, ]+' '{for(i=2;i<=NF;i++)printf $1"."$i"\n"}' file.in
awk의 필드 구분 기호가 정규식이라는 사실을 활용합니다.