의사코드는 다음의 연속이다.이 답변
gsed 's/|/1)/g' 's/|/2)/2g' 's/|/3)/3g' 's/|/5)/4g' 's/|/5)/5g'
<input.csv >output.csv
물론 이것은 작동하지 않습니다. 제가 관심 있는 것은 gsed
그러한 사이클을 어떻게 관리하느냐 하는 것입니다.
gsed
그러한 루프로 확장하는 방법은 무엇입니까 ?
답변1
위의 경우 다음과 같이 할 수 있습니다.
gsed 's/|/1)/; s/|/2)/; s/|/3)/; s/|/4)/; s/|/5)/'
예:
$ echo '| | | | |' | sed 's/|/1)/; s/|/2)/; s/|/3)/; s/|/4)/; s/|/5)/'
1) 2) 3) 4) 5)
|
이 방법은 행의 최대 개수를 미리 추정 하고 s/|/N)/
그에 따라 추가할 수 있는 경우에 효과적입니다.
한 줄의 최대 수를 예측할 수 없는 경우 |
에도 를 사용하여 계산할 수 있으며 gsed
버퍼를 유지하는 카운터를 사용하고 다음을 사용할 수 있습니다.이 영리한 장치저자: 브루노 하이블. 하지만 실제 구현은 약간 까다롭기 때문에 그대로 두겠습니다.마조히스트기민한 독자.
물론 가장 쉬운 방법은 다음을 사용하는 것입니다 awk
.
awk '{ cnt = 0; while(sub(/\|/, ++cnt ")")); print }'
입증하다:
$ echo '| | | | |' | awk '{ cnt = 0; while(sub(/\|/, ++cnt ")")); print }'
1) 2) 3) 4) 5)
답변2
또 다른 sed:
sed -n '1x;1s/^/12345/;1x;G;:t
s/|\(.*\n)\(.\)/\2)\1/;tt
P' <infile >outfile
awk
하지만 여기가 더 적합 할 수도 있습니다 .
더 복잡한 솔루션:
다른 질문의 결과를 고려하면 ...
Question ipsun; option 1 | option 2 | option 3 | option 4 | ... | option n
Que|stion ipsun; option 1 | option 2 | option 3 | option 4 | ... | option n
...그리고 그것을 전달합니다...
sed ' s/^/!/;/|/s/\(.*;\)*[^|]*/&\
|/g; s/.*\(\n\).*/::::::\1&\1::/' |
nl -d:: -hp^\) -s\)\ |
sed -e' /./{ s/^ *!//;P;d;:n' -e'};N;/\n$/!bn
s/[0-9 ]*\n *\([^;|)]*) |*\)|/ (\1/g;D'
...얻기 위해...
Question ipsun; option (1) | option (2) | option (3) | option (4) | ... (5) | option n (6)
Que|stion ipsun; option (1) | option (2) | option (3) | option (4) | ... (5) | option n (6)
무너질 것 같아요...
sed ' s/^/!/;/|/s/\(.*;\)*[^|]*/&\
)/g; s/.*\(\n\).*/::::::\1&\1::/' |..
.
...첫 번째 단계입니다. 출력 준비가 완료되었습니다 nl
.
nl
표준 유틸리티 중에서 고유한 기능을 가지고 있습니다.(대부분은 전체 입력 스트림을 하나의 응집력 있는 단위로 취급합니다)- 그럴 수 있으니까논리적으로입력 파일을 구분하여부분. nl
입력을 다음과 같이 나눕니다.머리글,몸, 그리고보행인각각논리 페이지그것은. 페이지의 세 섹션 각각에 대해 사용자는 서로 다른 번호를 지정할 수 있습니다.스타일각각에 대해, 그리고 각각에 대해논리 페이지사용자는 새로운 라인을 받을 수 있습니다계산.
위와 같이 sed
했습니다.
s/^/!/
- 다른 것이 없다면 s에 대한 섹션 구분 기호가 실수로 입력에 나타나는 것을 방지할 수 있지만
nl
처리 반대편에서 잘라낼 선행 공백에 대한 마커 역할도 합니다.nl
- 다른 것이 없다면 s에 대한 섹션 구분 기호가 실수로 입력에 나타나는 것을 방지할 수 있지만
/|/s...
- 이는 적어도 하나의 파이프와 명시적으로 일치하는 행에만 대체를 적용하려고 시도합니다
|
.
- 이는 적어도 하나의 파이프와 명시적으로 일치하는 행에만 대체를 적용하려고 시도합니다
...s/\(.*;\)*[^|]*/&\n|/g
- 이는 무엇이든 일치할 수 있는 패턴에 전역 대체를 적용합니다.(또는 심지어 아무것도)파이프 인데 때로는 뒤에 세미콜론이
|
없는 경우도 있습니다.;
- 0번 이상
\(.*;\)*
일치하기 때문에 대부분의 경우 빈 문자열과 일치합니다.*
그러나 일치자가 하나 이상의 세미콜론을 포함하는 줄에 하위 표현식을 처음 적용할 때;
줄의 시작 부분부터 마지막 세미콜론까지 전체 패턴 공간 범위를 효과적으로 건너뜁니다. - 이것의 목적은
[^|]*
발생하는 하위 문자열과의 일치를 방지하는 것입니다.앞으로세미콜론으로 구분하므로 건너뜁니다.질문전체 문자열의 일부입니다.
- 0번 이상
- 이 패턴이 나타날 때마다 해당 패턴이
&
자체로 대체되고 추가 패턴이 추가됩니다.\n|
.
- 이는 무엇이든 일치할 수 있는 패턴에 전역 대체를 적용합니다.(또는 심지어 아무것도)파이프 인데 때로는 뒤에 세미콜론이
s/.*\(\n\).*/::::::\1&\1::/
- 이는
\n
적어도 하나의 ewline을 6개의 콜론으로 포함하는 모든 패턴 공간을 대체하고, 그 다음에는 우리가 캡처한 ewline\1\n
,&
그 다음에는 우리가 캡처한 ewline\1\n
, 그리고 2개의 콜론으로 대체합니다. - 문자열을 사용하겠습니다
::
nl
다음과 같이섹션-d
구분 기호. 이 문자열 중 하나는 다음으로 시작합니다.nl
보행인세 개의 문자열이 1을 표시하는 섹션머리글- 그리고 새로운 논리 페이지. nl
~ 할 것이다오직구분 기호는 한 줄에 단독으로 나타나면 인식됩니다.
- 이는
...이 시점의 데이터 흐름은 다음과 같습니다.
::::: ! 옵션 1에 물어보세요. ||옵션 2 ||옵션 3 ||옵션 4 || ||옵션 n | :: ::::: !질문|ipsun;옵션 1 ||옵션 2 ||옵션 3 ||옵션 4 || ||옵션 n | ::
...이제 통과할 수 있어...
...|nl -d:: -hp^\) -s\)\ |...
-d::
- 이는 다음을 지정합니다.
::
구분자 문자열. nl
-d
입력의 각 구분 기호 문자열을 출력의 빈 줄로 바꿉니다 .nl
출력 줄의 시작 부분에 숫자를 삽입하거나 숫자 문자열의 길이와 일치하도록 번호가 지정되지 않은 줄의 시작 부분에 공백을 삽입합니다.- 따라서 출력에서 유일한 빈 줄은 구분 기호 문자열이었던 줄입니다.
- 이는 다음을 지정합니다.
-hp^\|
- 이것은
-h
지도자스타일 의미정규식 패턴과 일치하는 모든 줄에 번호를 매깁니다.. nl
에 있을 것이다머리글다음 항목만 포함하는 행 사이에 발생하는 각 행 시퀀스의 상태::::::
다른 하나는::
.- 기본
nl
번호오직신체 부위에는 번호가 매겨져 있지 않습니다.머리글또는보행인별말씀을요.
- 이것은
-s\)\
nl
이것은 번호가 매겨진 각 줄의 머리글과 그 앞에 삽입된 번호 사이에 삽입 될 구분자 문자열입니다 .
...이 시점의 데이터 흐름은 다음과 같습니다.
! 옵션 1에 물어보세요. 1) ||옵션 2 2) ||옵션 3 3)||옵션 4 4) || 5)||옵션 n 6) | !질문|ipsun;옵션 1 1) ||옵션 2 2) ||옵션 3 3)||옵션 4 4) || 5)||옵션 n 6) |
...마침내 이 문제를 처리할 수 있는 방법은 다음과 같습니다.
sed -e' /./{s/^ *!//;P;d;:n' -e '};N;/\n$/!bn
s/[0-9 ]*\n *\([^;|)]*) |*\)|/ (\1/g;D'
/./{...
- 이는 하나 이상의 문자가 포함된 모든 줄에서 일치 중심 기능을 시작합니다.
- 그 뒤에는 여러 명령이 있을 수 있지만 함수의 상위 주소와 처음 일치하는 패턴 공간에만 해당됩니다.
...{s/^ *!//
nl
여기서는 일치하는 행의 머리 부분에서 삽입된 모든 공백과 삽입된 앞머리를 잘라냅니다.
P;d;:n
- 이는 패턴 공간의 첫 번째 줄
P
에 인쇄됩니다 .\n
- 그런 다음
d
패턴 공간을 삭제합니다. - 그런 다음 분기 레이블을 정의합니다
:n
. - 이제부터는 빈 줄로 시작하는 일련의 줄만 처리합니다.
- 이는 패턴 공간의 첫 번째 줄
N
N
이는 확장 입력 라인을 가져 와서\n
ewline 문자 뒤의 패턴 공간에 추가합니다.
/\n$/!bn
$
패턴 공간이 ewline으로 끝나지 않더라도 (\n
ext 라인이 비어 있으면 그럴 것입니다), 우리는 항상 label-stacked 입력으로 돌아갑니다.N
b
:n
s/[0-9 ]*\n *\([^;|)]*) |*\)|/ (\1/g'
g
부분교체 입니다 .- 모든 시퀀스를 대체합니다...
*
0개 이상의[0-9 ]
문자- 다음은
\n
ewline 입니다 - 그 뒤에
*
0개 이상이 옵니다.<스페이스> - 그 뒤에
*
0개 이상의^
콜론이나 파이프가 아닌 문자가 옵니다. - 오른쪽
)
괄호 다음에 - 뒤에
|
파이프가 올 수 있음 |
그 뒤에는 파이프가 따라와야 합니다.^
콜론/파이프가 아닌 문자, 닫는 괄호 및 파이프 만 포함됩니다 .
D
- 이제 패턴 공간의 첫 번째 줄을
D
삭제합니다.\n
(시퀀스가 빈 줄로 시작하기 때문에 이것이 첫 번째 문자입니다)나머지 부분을 다시 스크립트 상단으로 보내P
다음 새 주기에서 공간과 폭발을 다듬고 인쇄합니다.
- 이제 패턴 공간의 첫 번째 줄을
최종 결과는 다음과 같습니다.
Question ipsun; option (1) | option (2) | option (3) | option (4) | ... (5) | option n (6)
Que|stion ipsun; option (1) | option (2) | option (3) | option (4) | ... (5) | option n (6)