GNU Sed에서 첫 번째를 1)로 바꾸고 두 번째를 2)로 바꿉니다.

GNU Sed에서 첫 번째를 1)로 바꾸고 두 번째를 2)로 바꿉니다.

의사코드는 다음의 연속이다.이 답변

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/\(.*;\)*[^|]*/&\n|/g
    • 이는 무엇이든 일치할 수 있는 패턴에 전역 대체를 적용합니다.(또는 심지어 아무것도)파이프 인데 때로는 뒤에 세미콜론이 |없는 경우도 있습니다.;
      • 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이는 확장 입력 라인을 가져 와서 \newline 문자 뒤의 패턴 공간에 추가합니다.
  • /\n$/!bn
    • $패턴 공간이 ewline으로 끝나지 않더라도 ( \next 라인이 비어 있으면 그럴 것입니다), 우리는 항상 label-stacked 입력으로 돌아갑니다.Nb:n
  • s/[0-9 ]*\n *\([^;|)]*) |*\)|/ (\1/g'
    • g부분교체 입니다 .
    • 모든 시퀀스를 대체합니다...
      • *0개 이상의 [0-9 ]문자
      • 다음은 \newline 입니다
      • 그 뒤에 *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)

관련 정보