다음과 같은 입력이 있습니다(1,000개 행). sed
동일한 처음 세 필드와 중복 행을 병합하는 명령을 원합니다.다음에 추가분야만 다르거나삭제"해당 사항 없음":
D04005;4;279;0;0;SSM-4-1
D04005;5;40;0;0;SSM-5-1
LE040A;1;363;(26.3);N/A;SM-1-1
LE040A;1;363;(27.4);N/A;SM-1-2
예상 출력:
D04005;4;279;0;0;SSM-4-1
D04005;5;40;0;0;SSM-5-1
LE040A;1;363;(26.3);(27.4);SM-1-1/SM-1-2
답변1
sed ':n
s|;N/A;|;|g;$!N
s|^\(\([^;]*;\)\{3\}\)\(.*\)\n\1|\1\3;|;tn
P;D
' <<\IN
D04005;4;279;0;0;SSM-4-1
D04005;5;40;0;0;SSM-5-1
LE040A;1;363;(26.3);N/A;SM-1-1
LE040A;1;363;(27.4);N/A;SM-1-2
LE040A;1;363;(28.5);N/A;SM-1-3
LE040A;1;363;(29.6);N/A;SM-1-4
IN
입력의 각 시퀀스에 대해 계속해서 t
est로 분기하여 각 시퀀스의 꼬리만 병합합니다.
이것은 이식 가능하지만 사용할 수 있다면 작성하기가 더 쉬울 것입니다.-E
확장 정규식(BSD나 GNU 버전을 사용하는 것처럼)...
sed -E ':n
s|;N/A;|;|g;$!N
s|^(([^;]*;){3})(.*)\n\1|\1\3;|;tn
P;D'
한 줄에 모든 내용을 작성하려면 다음을 수행하십시오.
sed -Ee:n -e's|;N/A;|;|g;$!N;s|^(([^;]*;){3})(.*)\n\1|\1\3;|;tn' -eP\;D
...효과가 있겠지만 별로 마음에 들지 않았습니다.한 줄그렇게...
어쨌든 첫 번째 출력은 다음과 같습니다.
산출
D04005;4;279;0;0;SSM-4-1
D04005;5;40;0;0;SSM-5-1
LE040A;1;363;(26.3);SM-1-1;(27.4);SM-1-2;(28.5);SM-1-3;(29.6);SM-1-4
다음으로 시작하는 후행 필드를 이동할 수도 있습니다.SM-
줄 끝까지 연결하고 각각을 로 구분하면 /
다음이 작동해야 한다고 생각합니다.
sed -E ':n
s|;N/A;|;|g
s|;(SM-[^;]*)$|/\1|;$!N
s|^(([^;]*;){3})(.*)\n\1|\1\3;|;tn
P;D'
그런데 필요한 것이 무엇인지 더 명확하고 구체적으로 설명하면 이 작업이 더 쉽고 빨라집니다. 동일한 처음 세 필드만 병합하고 싶지 않은 것 같습니다.어느두 개의 연속 행 및 일치하는 필드 제거N/A
~에서어느선을 그은 다음 이동SM-
필드 끝어느철사. 대신에, 당신이 말하는 이 모든 개별 직업은 실제로 같은 것을 의미하고 당신이 정말로 다음과 같은 것을 원하는 것 같습니다:
- 입력 줄에 세 개의 영숫자, 세미콜론으로 구분된 필드, 괄호로 묶인 부동 소수점 필드, 또 다른 콜론 구분 기호가 차례로 포함되어 있는 경우
N/A
필드에서 다음을 수행해야 합니다.- 다음 행도 이 설명과 일치하는지 확인하고, 그렇다면 현재 행과 다음 행의 처음 세 필드를 비교합니다.
- 일치하는 항목이 발견되면 다음 행의 마지막 필드만 유지되고 재귀적으로 다시 시도됩니다.
- 그럼에도 불구하고 일치하는 필드는 항상 제거됩니다.
N/A
, 마지막 것을;
로 바꿉니다/
.
- 어쨌든, 표준 출력으로 남은 모든 것을 인쇄하십시오.
차이점이 보이나요? 단일 초기 조건을 기반으로 수행되는 일련의 작업입니다. 이렇게 명확하게 설명할 수 있다면 일치 항목이 처리 시간의 일반성을 보충할 필요가 없습니다.
내가 맞다면 다음이 작동합니다.
sed ' \|;N/A;|!b
s||/|;$!N
\|^\(.*(\)\(.*)\)\(.*\)\(\n\1\)\(.*)\)|!P
s||\4\2;(\5\3|;D
' <<\IN
D04005;4;279;0;0;SSM-4-1
D04005;5;40;0;0;SSM-5-1
LE040A;1;363;(26.3);N/A;SM-1-1
LE040A;1;363;(27.4);N/A;SM-1-2
LE040A;1;363;(28.5);N/A;SM-1-3
LE040A;1;363;(29.6);N/A;SM-1-4
IN
D04005;4;279;0;0;SSM-4-1
D04005;5;40;0;0;SSM-5-1
LE040A;1;363;(26.3);(27.4);(28.5);(29.6)/SM-1-1/SM-1-2/SM-1-3/SM-1-4
...여기있어-E
라인에...
sed -e'\|;N/A;|!b' -e's||/|;$!N;\|^\(.*(\)\(.*)\)\(.*\)\(\n\1\)\(.*)\)|!P;s||\4\2;(\5\3|;D'
...또는-E
확장된 구문...
sed -Ee'\|;N/A;|!b' -e's||/|;$!N;\|^(.*\()(.*\))(.*)(\n\1)(.*\))|!P;s||\4\2(\5\3|;D'
답변2
송신기:
@(repeat)
@ (cases)
@id;@f2;@f3;@val1;@nil;@sm1
@id;@f2;@f3;@val2;@nil;@sm2
@ (do (put-line `@id;@f2;@f3;@val1;@val2;@sm1/@sm2`))
@ (or)
@line
@ (do (put-line line))
@ (end)
@(end)
$ txr data.txr data
D04005;4;279;0;0;SSM-4-1
D04005;5;40;0;0;SSM-5-1
LE040A;1;363;(26.3);(27.4);SM-1-1/SM-1-2
답변3
sed -r ':a;N;s!;N/A!!g;s/^(([^;]*;){3})(.*)\n\1/\1\3;/;T;s!^(([^S][^;]*;){3,})(S*SM-[^;]*);(([^S][^;]*;){1,})(.*)!\1\4\3/\6!;ta' inputfile
출력에서 단 6개 필드의 주석에 대한 암시적 수학은 쌍만 있음을 나타내지만 이는 루프 버전이며 일치 시 출력 SM-1-1/SM-1-2가 변경됩니다.