입력으로 다음 데이터가 있습니다.
A 1,2
B 3,2,5
C 6,7
D 1,3,5,8
AWK를 사용하여 다음 출력을 어떻게 얻을 수 있나요?
A 1
A 2
B 3
B 2
B 5
C 6
C 7
D 1
D 3
D 5
D 8
답변1
$ awk -F '[ ,]' '{ for (i = 2; i <= NF; ++i) print $1, $i }' file
A 1
A 2
B 3
B 2
B 5
C 6
C 7
D 1
D 3
D 5
D 8
이는 행을 공백이나 쉼표로 구분된 필드로 구성된 것으로 처리합니다. 각 행에 대해 awk
프로그램은 행 끝까지 두 번째 필드를 반복합니다. 각 필드에 대해 출력됩니다.첫 번째현재 필드와 함께 행의 필드.
답변2
awk '{gsub(/,/, "\n" $1 " "); print}' file
이 솔루션에서는 ,
각 " "를 다음으로 대체합니다."\n$1 "
답변3
sed
확장 정규식 엔진을 활성화 하면 다음과 같은 작업을 수행할 수 있습니다.
$ sed -re '
s/^((\S+\s+)[^,]+),/\1\n\2/
P;D
' file
우리는 Perl
할 수있어:
$ perl -F'\s+|,' -lane '
print join $", splice @F, 0, 2, $F[0] while @F > 1;
' file
현재 레코드를 공백이나 쉼표로 분할하고 0 인덱스 배열에 저장합니다 @F
.
배열의 처음 두 요소를 연결하고 단일 공백으로 결합하여 $"
인쇄합니다. 또한 삭제된 두 요소를 모두 첫 번째 요소로 바꿉니다. 단 하나의 요소만 남을 때까지 이 과정을 반복합니다.
답변4
sed
이것이 옵션 이라면 다음과 같이 할 수 있습니다.
sed -E ':a s/^([^ ]* )(.*),([^,]*$)/\1\2\n\1\3/; ta' infile
다음 입력을 고려하십시오.
B 2,3,5,6
C 6,7
D 1,3,5,8
- 이는 첫 번째 열 을
([^ ]* )
캡처합니다(공백이 구분 기호라고 가정).B
두번째그 다음에공간). - 이는
(.*),
마지막 쉼표까지 모든 것을 캡처합니다.2,3,5
이는
([^,]*$)
줄의 나머지 부분을 캡처합니다(예: 매번 캡처하는 마지막 쉼표 뒤의 마지막 필드).6
따라서
\1\2\n\1\3
첫 번째 줄의 첫 번째 루프가 실행될 때의 결과는 다음과 같습니다.sed -E ':a s/^([^ ]* )(.*),([^,]*$)/\1\2\n\1\3/;q ;ta' infile B 2,3,5 B 6
다음 루프 실행의 결과는 다음과 같습니다.
B 2,3 B 5 B 6
- 다음에 달리면...
마지막으로 마지막 루프 실행의 첫 번째 줄은 다음과 같이 출력됩니다.
sed -E ':a s/^([^ ]* )(.*),([^,]*$)/\1\2\n\1\3/ ;ta ;q' infile B 2 B 3 B 5 B 6
이제 다음 줄을 읽고 모든 줄이 계속되고 완료될 때까지 동일한 과정을 수행합니다.