"1:2, 3, 4, 5"와 같은 목록을 "1.2, 1.3, 1.4, 1.5"로 영리하게 변환하세요.

"1:2, 3, 4, 5"와 같은 목록을 "1.2, 1.3, 1.4, 1.5"로 영리하게 변환하세요.

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

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>이는 두 줄입니다( 일부 구현으로 대체 가능 ).\nsed

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을 사용하는 등 보다 자세한 유형의 루프를 사용해야 합니다 .:bt

답변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의 필드 구분 기호가 정규식이라는 사실을 활용합니다.

관련 정보