공백을 줄바꿈으로 바꾼 후 sed를 다시 호출해야 하는 이유는 무엇입니까?

공백을 줄바꿈으로 바꾼 후 sed를 다시 호출해야 하는 이유는 무엇입니까?

주어진 파일에 포함된 모든 바이트를 8진수 형식으로 각각 한 줄에 나열하고 싶습니다.

이것이 작동하는 이유:

#!/bin/sh --

newline='
'

od -v -A n -t o1 -- /tmp/file | \
sed -e "s/ /\\${newline}/g" | \
sed -e '/^$/d'

대신에:

#!/bin/sh --

newline='
'

od -v -A n -t o1 -- /tmp/file | \
sed -e "s/ /\\${newline}/g" -e '/^$/d'

작업을 완료하려면 왜 sed를 두 번 호출해야 합니까?

참고로 추가 처리가 없는 출력은 od다음과 같습니다.

         047 124 167 141 163 040 142 162 151 154 154 151 147 054 040 141
         156 144 040 164 150 145 040 163 154 151 164 150 171 040 164 157
         166 145 163 012 011 104 151 144 040 147 171 162 145 040 141 156
         144 040 147 151 155 142 154 145 040 151 156 040 164 150 145 040
         167 141 142 145 072 012 101 154 154 040 155 151 155 163 171 040
         167 145 162 145 040 164 150 145 040 142 157 162 157 147 157 166
         145 163 054 012 011 101 156 144 040 164 150 145 040 155 157 155
         145 040 162 141 164 150 163 040 157 165 164 147 162 141 142 145
         056 012

답변1

sed표현식은 전체 패턴 공간에서 작동합니다. 루프가 시작될 때 행이 패턴 공간으로 읽혀지고 sed주어진 각 표현식이 해당 데이터에 적용됩니다.

코드의 두 번째 변형에서는 대체를 통해 패턴 공간에 개행 문자를 삽입합니다. 두 번째 표현식은 /^$/d패턴 공간의 각 라인이 아닌 전체 패턴 공간에서 계속 작동합니다. 즉, 패턴이 일치하지 않고(버퍼가 비어 있지 않기 때문에) 패턴 공간이 일치하지 않습니다. 삭제되었습니다. /^$/d로 변경 하면 s/\n\{2,\}//g두 개 이상의 연속된 줄 바꿈이 제거됩니다(이로 인해 출력에 빈 줄이 생성됨).회의이미 직장에 있어요.

sed이는 두 번째 변형이 첫 번째 의 출력을 읽는 코드의 첫 번째 변형과 대조됩니다 sed. 이 경우 두 번째는 sed생성된 각 행을 읽습니다.개별적으로, 빈 항목을 삭제합니다.

sed간단히 말해서, 패턴 공간에 줄 바꿈을 추가해도 생성된 각 줄이 나머지 표현식에 대한 별도의 입력으로 다시 고려 되지 않습니다 .


대체 솔루션:

od -v -A n -t o1 -- /tmp/file |
sed -e 's/ \{2,\}//g' -e 'y/ /\n/'

첫 번째 sed표현식은 s/ \{2,\}//g두 개 이상의 연속 공백을 제거하고 두 번째 표현식은 나머지 공백을 개행 문자로 변환합니다( POSIX에서도 \n명령이 허용함 ).ysed

또는 남은 공백을 줄 바꿈으로 변환하기 전에 측면 공백을 모두 제거할 수 있습니다.

od -v -A n -t o1 -- /tmp/file |
sed -e 's/^ *//' -e '$s/ *$//' -e 'y/ /\n/'

(출력의 마지막 줄에만 od후행 공백이 있을 수 있으므로 $이를 두 번째 표현식의 주소로 사용했습니다.)

또는 다음 명령을 사용하는 것이 더 간단할 수 있습니다 awk.

od -v -A n -t o1 -- /tmp/file |
awk '{ for (i = 1; i <= NF; ++i) print $i }'

답변2

이는 대체를 수행한 후에 출력 파일에 빈 줄만 존재하기 때문입니다. 왜 안 돼

od -v -An -to1 -w1 -- file 

?

관련 정보