sed 명령 "n"과 "b"의 차이점은 무엇입니까?

sed 명령 "n"과 "b"의 차이점은 무엇입니까?

b레이블은 허용하지만 n레이블은 허용하지 않고 레이블 없이 사용하려면 b...a 없이 전달된 인수의 끝에(적어도 한 줄에 대해) 레이블을 배치해야 한다는 명백한 구문 지점 외에도 레이블과 an은 똑같은 일을 하는 것 같습니다.-ebn

이거 진짜야? 아니면 제가 인지하지 못한 미묘한 차이가 있나요? 어떤 조건에서 그들은 같은 일을 하고, 어떤 조건에서는 같은 일을 하지 않습니까?

답변1

두 예제는 동일하며 n단지 b. 출력이 다른 것을 볼 수 있습니다.

$ echo $'1\n2\n3' | sed 's/./AA/; n; s/./BB/'
AA
BB
AA
$ echo $'1\n2\n3' | sed 's/./AA/; b; s/./BB/'
AA
AA
AA

b명령의 끝으로 분기합니다. n나머지 명령을 계속 실행합니다. 따라서 에 대해서는 b대체가 s/./BB/수행되지 않습니다. 사용하는 경우 n한 줄씩 걸러서 실행합니다.

(위 명령은 GNU sed를 사용하여 실행되었습니다. BSD/OSX sed의 경우 OP에서 지적했듯이 코드 형식에 대한 약간의 변경이 필요합니다.)

답변2

글쎄요...
ranch b명령은 다음과 같습니다.

[2addr]b[label]
    Branch to :label. If label is not specified, branch to the end of the script.

외부 n명령:

[2addr]n
    If auto-print is not disabled, print the pattern space, then, regardless,
    replace the pattern space with the next line of input. If no next line of
    input is available, branch to the end of the script.

여기서 주요 차이점은 다음과 같습니다.

b무조건 스크립트 끝으로 분기
n하고 더 이상 입력이 없을 경우에만 스크립트 끝으로 분기합니다.

입력이 다음과 같다고 가정합니다.

fdue
four
four
fdue
four

f나는 로 바꾸고 싶지만 다른 모든 라인이 아닌 t일치하는 라인에서만 교체하고 싶습니다 . 한 가지 방법은fourui

sed '/four/{s/f/t/;b;};s/u/i/' infile

출력은 예상대로입니다

fdie
tour
tour
fdie
tour

n이제 대신 사용할 때 어떤 일이 발생하는지 살펴보겠습니다 b.

fdie
tour
foir
fdie
tour

두 번째 줄 일치 항목은 간단한 이유로 스크립트의 맨 위로 돌아가지 않도록 four편집되었습니다 . 대신 그 이후 줄을 처리하는 명령은 의도한 것이라고 생각조차 하지 않습니다. 그러나 마지막 줄에서는 첫 번째 대체만 수행되므로 후속 명령은 더 이상 실행되지 않습니다.foirtournsnsn

요약하자면, 다음 조건이 충족되면 이 두 명령은 기능적으로 동일합니다.

  • 스크립트는 입력의 마지막 줄(앞으로실행 n) 또는
  • 어떤 경우에도 소개된 다음 줄은 1n 이전의 명령으로 편집하면 안 됩니다 (즉, 다음 줄은 연결된 주소가 아닙니다).nb

n현재 패턴 공간을 인쇄하고 다음 줄을 가져오는 것이 사실이지만 b그것만으로도 동일한 효과가 있습니다. 스크립트 끝으로 분기하는 것은 자동으로 인쇄하는 것을 의미하며( sedcall 을 사용하지 않는 -nn인쇄되지 않습니다) 그런 다음 자동으로 다음 줄을 읽습니다. 내가 말했듯이, 가장 큰 차이점은 n스크립트 끝으로 점프할 수 없다는 것입니다(그리고 스크립트의 맨 위로 돌아갈 수 없습니다). sed남은 명령을 실행하기만 하면 됩니다.마지막 줄에 없으면).



1 내가 말했듯이 스크립트의 맨 위로 돌아갈 수 없기 때문에 이 명령은 실행되지 않습니다 . n나머지 명령은 발생해서는 안 되는 줄을 편집할 수 있습니다.

답변3

"branch" 명령( b)은 편집 스크립트에서 미리 정의된 레이블로 분기하거나 레이블이 없는 경우 스크립트 끝으로 분기하는 반면 "next" 명령( n)은 입력의 다음 줄을 읽습니다. 또한 "next" 명령은 출력 억제가 사용되지 않는 한 다음 라인(보통 방금 읽은 라인)을 읽기 전에 현재 패턴 공간을 출력합니다 -n.

두 가지 다른 작업을 수행하는 두 가지 다른 편집 명령입니다. "next" 명령은 스크립트 끝까지 분기를 일으키지 않으며, "branch" 명령은 현재 패턴 공간을 출력하거나 자체적으로 새 줄을 읽지 않습니다.

간단한 예(GNU 사용 sed):

$ cat lines
1
2
3
4
5

$ gsed -n '3{n;p;p;}' lines
4
4

세 번째 줄의 경우 스크립트는 다음 줄을 읽고 두 번 인쇄합니다. 네 번째 줄은 두 번 인쇄됩니다.

$ gsed -n '3{b;p;p;}' lines

스크립트가 "print"( p) 명령으로 분기되므로 출력이 생성되지 않습니다.

없이 실행하는 경우 -n:

$ gsed '3{n;p;p;}' lines
1
2
3
4
4
4
5

세 번째 줄은 n스크립트의 명령 출력입니다. 네 번째 줄은 세 번 출력되고, p다음 줄을 읽은 후 스크립트에서 두 번, 기본 명령으로 한 번 출력됩니다. np

$ gsed '3{b;p;p;}' lines
1
2
3
4
5

"branch" 명령은 스크립트에서 이 두 줄을 우회하므로 이 줄은 p기본 명령에 의해 출력 됩니다.p

결론적으로:n다음 줄을 로드하고 다음 명령어 처리를 계속하여 b지정된 분기(이름이 지정된 경우) 또는 스크립트 끝으로 이동합니다. 두 경우 모두 sed가 스크립트 끝에 도달하면 나머지 입력은 평소와 같이 스크립트 시작 부분부터 처리됩니다.

관련 정보