이 명령은 왜 다른 모든 줄에서만 작동합니까?

이 명령은 왜 다른 모든 줄에서만 작동합니까?

내가 실행하면 \ls | xargs -I {} echo {} | sed 'N;s/\n/xxxxxxxxx/'다음과 같은 결과를 얻습니다.

- Books aliasxxxxxxxxxA New Kind of Science
Computability-and-Logic.pdfxxxxxxxxxComputability-and-Logic_k2opt.pdf
Hein J. L. - Prolog Experiments in Discrete Mathematics, Logic, and Computability (2005).pdfxxxxxxxxxHein J. L. - Prolog Experiments in Discrete Mathematics, Logic, and Computability (2005)_k2opt.pdf
How Automated Recommendations Affect the Playlist Creation Behavior of Users.pdfxxxxxxxxxHow Automated Recommendations Affect the Playlist Creation Behavior of Users_k2opt.pdf
Lumanote- A Real-Time Interactive Music Composition Assistant.pdfxxxxxxxxxgeMsearch- Personalized Explorative Music Search.pdf
research_report_dc_02.pdfxxxxxxxxxresearch_report_dc_02_k2opt.pdf
thebookofshaders.pdfxxxxxxxxxthebookofshaders_k2opt.pdf

출력이 왜 다음과 같지 않은지 이해할 수 없습니다.

- Books aliasxxxxxxxxxA New Kind of SciencexxxxxxxxxComputability-and-Logic.pdfxxxxxxxxxComputability-and-Logic_k2opt.pdfxxxxxxxxxHein J. L. - Prolog Experiments in Discrete Mathematics, Logic, and Computability (2005).pdfxxxxxxxxxHein J. L. - Prolog Experiments in Discrete Mathematics, Logic, and Computability (2005)_k2opt.pdfxxxxxxxxxHow Automated Recommendations Affect the Playlist Creation Behavior of Users.pdfxxxxxxxxxHow Automated Recommendations Affect the Playlist Creation Behavior of Users_k2opt.pdf

답변1

$ seq 10  | sed 'N;s/\n/+/'
1+2
3+4
5+6
7+8
9+10

N패턴 공간에 다음 라인을 추가하고 s두 라인을 결합한 +다음 sed해당 라인을 인쇄하고 다음 입력 라인(라인 3과 4가 +결합되는 위치)에 대한 스크립트를 반복합니다.

당신은해야합니다

$ seq 10 | sed 'N;N;N;N;N;N;N;N;N;s/\n/+/g'
1+2+3+4+5+6+7+8+9+10

또는 sed 스크립트에서 루프를 사용하여 모든 줄을 연결합니다.

$ seq 10 | sed -e :1 -e '$!N;s/\n/+/;t1'
1+2+3+4+5+6+7+8+9+10

전체 입력을 패턴 공간으로 흡수하므로 대용량 파일에 맞게 확장되지 않습니다.

문자 구분 기호를 사용하여 줄을 연결하려면 다음을 사용할 수 있습니다 paste.

$ seq 10 | paste -sd + -
1+2+3+4+5+6+7+8+9+10

전체 입력을 메모리에 로드하지 않는 다중 문자 구분 기호의 경우:

$ seq 10 | awk -v sep=-+- -vORS= 'NR>1 {print sep}; 1; END {if (NR) print RS}'
1-+-2-+-3-+-4-+-5-+-6-+-7-+-8-+-9-+-10

답변2

주석이 달린 스크립트 sed:

# Append the next line of input to the pattern space with an embedded newline
N

# Replace the embedded newline with the string xxxxxxxxx
s/\n/xxxxxxxxx/

# (implicit print, start next cycle, overwriting the pattern space with the next line)

따라서 한 줄을 읽고, 한 줄을 추가하고, 교체 + 출력을 수행합니다. 그런 다음 세 번째 줄을 읽고 네 번째 줄을 추가한 다음 + 출력을 바꿉니다.

수집하고 싶다면모두두 가지 방법으로 이를 수행할 수 있습니다 sed.

  1. 명시적인 루프를 사용하십시오: :top; N; $!btop; s/\n/xxxxxxxxx/g"다음 줄을 추가하고 아직 끝나지 않았다면 다시 수행하고 모든 줄 바꿈을 바꿉니다".

  2. 예약된 공간 사용: 1{h;d;}; H; ${x;s/\n/xxxxxxxxx/g;p;}; d즉, "첫 번째 줄을 예약된 공간에 복사하고 입력에서 삭제하고 다른 모든 줄도 거기에 추가한 다음 입력에서 제거합니다. 그러나 마지막 줄에 도달하면 예약된 공간을 바꾸고 줄바꿈을 하고 결과를 인쇄합니다."

이 두 방법의 주요 차이점은 첫 번째 방법은 끝까지 첫 번째 루프를 종료하지 않고 패턴 공간에 문자열을 작성하는 반면, 두 번째 방법은 입력의 각 라인에 대해 끝까지 실행하고 결과를 보유 공간에 축적한다는 것입니다. .


그것을 보는 또 다른 방법은 를 사용하는 것입니다 awk.

귀하의 sed코드는 본질적으로

awk '{ line = $0; getline; print line "xxxxxxxxx" $0 }'

당신이 원하는 것은

awk '{ line = (line == "" ? $0 : line "xxxxxxxxx" $0 ) } END { print line }'

이는 사용 중인 예약된 공간을 시뮬레이션합니다 sed.

또는,

awk '{ line = $0; while (getline > 0) line = line "xxxxxxxxx" $0; print line }'

이는 명시적 루프를 사용하여 시뮬레이션됩니다 sed.

답변3

이는 sed가 한 줄씩 처리하기 때문에 발생합니다. 다음과 같이 반복해야 합니다. sed -e ':again' -e 'N;s/\n/xxxxx/' -e 'tagain'또는 더 쉬운 방법은 다음과 같이 사용하는 것입니다.tr "\n" "xxxxx"

관련 정보