다음 줄을 "분할"하는 방법을 아는 사람이 있습니까? (이것은 단지 예일 뿐입니다.)
mercedes|$40000|black|$42000|white|$41000|red
audi|$31000|blue|$10000|white
mercedes|$5000|blue
내 예상 결과는 다음과 같습니다
mercedes|$40000|black
mercedes|$42000|white
mercedes|$41000|red
audi|$31000|blue
audi|$10000|white
mercedes|$5000|blue
감사해요
답변1
awk
두 번째 필드로 시작하는 각 줄의 필드 쌍을 출력하고 각 출력 쌍 앞에 해당 줄의 첫 번째 필드를 추가하는 간단한 스크립트입니다.
$ awk -F '|' 'BEGIN { OFS=FS } { for (i = 2; i+1 <= NF; i += 2) print $1, $i, $(i+1) }' file
mercedes|$40000|black
mercedes|$42000|white
mercedes|$41000|red
audi|$31000|blue
audi|$10000|white
mercedes|$5000|blue
이는 입력이 예상한 대로라고 가정합니다. 즉, 최종 데이터는 세 개의 열로 구성되어야 합니다. 이는 입력이 엄격하게 준수되어야 함을 의미합니다.
title|pair 1a|pair 1b|pair 2a|pair 2b|...|pair Na|pair Nb
답변2
awk -F'[|]' '{ for(i=3; i<NF; i+=2) sub($i, $i ORS $1) }1' infile
첫 번째 매개변수에 유의하세요.sub(regexp, replacement [, target])
기능~이다정규식그래서 그것은 $i
다음과 같이 취급 됩니다정규식.
자세히 알아보기sub(), gsub() 및 gensub() 함수의 '\' 및 '&'이 함수의 두 번째 매개변수에 대해서도 마찬가지입니다.
또는 위에서 언급한 sub() 문제 없이 다음과 같이 수행하십시오.
awk 'BEGIN{ FS=OFS="|" } { for(i=3; i<NF; i+=2) $i= $i ORS $1 }1' infile
답변3
python
처음 두 필드를 채우려면 모듈 에 itertools
첫 번째 필드를 반복적으로 제공하십시오 .
python3 -c 'import sys
import itertools as it
ifile = sys.argv[1]
ofs = fs = "|"
with open(ifile) as f:
for l in f:
L = l.rstrip("\n").split(fs)
for a,b in zip(it.repeat(L.pop(0)),zip(*[iter(L)]*2)):
print(a,*b,sep=ofs)
' file
perl
또한 첫 번째 필드뿐만 아니라 선행 2+3 필드를 인쇄한 다음 두 번째 및 세 번째 필드를 삭제하여 다음 필드가 대신되도록 하는 경우에도 작동합니다.
perl -F'[|]' -lane '$,="|";
print $F[0], splice(@F,1,2)
while @F > 3;
print @F;
' file
GNU sed
확장 정규식 모드를 활성화합니다 -E
.
- 세 번째 필드의 끝에 표시하면 필드 1에서 필드 3까지 인쇄할 준비가 됩니다.
- 다음 인쇄 라운드를 준비하기 위해 세 번째 필드 다음에 첫 번째 필드를 복사합니다.
sed -Ee '
s/[|]/\n/3;P
s/^([^|]+[|]).*\n/&\1/;D
' file
설명하다:
- 다음과 같은 줄을 상상해 보세요.
- 자동차 브랜드 | p1 | c2 |
- 우리는 브랜드가 별도의 줄에 있는 가격/색상 튜플과 쌍을 이루기를 원합니다.
- 세 번째 파이프 구분 기호를 개행 문자로 바꿉니다.
s/[|]/\n/3
- 이제 패턴 공간을 시각화합니다.
- 자동차 브랜드 | c1 \n p2 | c1 \n p2 |
- sed 명령
P
(대문자 pee)은 첫 번째 개행 문자까지 표준 출력으로 인쇄합니다. - 이 단계의 출력은 다음과 같습니다.
- 자동차 브랜드 |
- 이것이 첫 번째 가격/색상 쌍입니다. 지금 해야 할 일은 자동차 브랜드를 다음 가격/색상 쌍으로 복사하는 것입니다.
s/^([^|]+[|]).*\n/&\1/
- 대괄호는 일치된 항목, 즉 첫 번째 파이프 구분 기호를 포함한 선행 데이터를 기억합니다. 개행 문자까지 일치합니다. 교체 부품은 우리 기억에 있는 (자동차 브랜드|)와 일치하는 부품 (&)입니다.
- 이제 패턴 공간은 Car_brand | c1 \n 자동차 브랜드 | c2 |
- 이것디elete 명령은 첫 번째 개행 문자가 나올 때까지 계속됩니다.
- 이제 패턴 공간은 Car _brand | c2 |
- 이 명령의 속성은
D
첫 번째 개행 문자까지 제거하고 나머지를 제공한 후 나머지 패턴 공간에 sed 코드를 다시 적용한다는 것입니다. - 간단히 말해서 이는 반복 작업에 해당합니다.
결과:
mercedes|$40000|black
mercedes|$42000|white
mercedes|$41000|red
audi|$31000|blue
audi|$10000|white
mercedes|$5000|blue
답변4
그리고 perl
:
perl -F"\|" -le '$,="|";
for (my $a=1;$a<@F;$a+=2)
{print $F[0],$F[$a], $F[$a+1]}' input
-F"\|"
입력 필드 구분 기호는 다음과 같이 설정됩니다.|
$,="|";
출력 필드 구분 기호는 다음과 같이 설정됩니다.|
$a<scalar @F;
Perl의 필드는 0부터 시작하므로 이는scalar @F
총 필드 수를 알려줍니다 .$a<scalar @F
이것은답변@Kusalananda 작성 그러나 perl
.