sed: 정규식 입력 버퍼 길이가 INT_MAX보다 깁니다.

sed: 정규식 입력 버퍼 길이가 INT_MAX보다 깁니다.

다양한 작업을 수행하는 대용량 파일이 있는데 방금 이 오류가 발생했습니다. 인터넷 검색을 시도했지만 결과를 찾지 못했습니다.

sed: regex input buffer length larger than INT_MAX

내 의도는 각 줄을 인용하고 쉼표를 추가한 다음 전체 파일을 (한 줄로) 대괄호로 묶는 것입니다. 예를 들어 다음을 입력합니다.

The quick brown fox
jumps over
the lazy dog.

다음 결과를 생성해야합니다

["The quick brown fox","jumps over","the lazy dog.",]

입력 파일에는 따옴표가 포함되어 있지 않은 것으로 가정됩니다.

내가 실행하는 코드는 다음과 같습니다.

cat "${FILE}" | sed -e 's/.*/"&",/' | sponge "${FILE}"

truncate --size=-1 "${FILE}"

cat "${FILE}" |  sed -z 's/.*/[&]/' | tr --delete '\n' | sponge "${FILE}"

sed 버전:

sed --version
sed (GNU sed) 4.5

어떤 아이디어가 있나요?

답변1

귀하의 질문이 이상합니다. "...이 오류가 방금 나타났습니다. 인터넷 검색을 시도했지만 결과를 찾지 못했습니다."라고 말하면 무슨 일이 일어나고 있는지 모르는 것 같습니다. 하지만 당신은 이해하고 있지 않습니까? 라고 말하면 읽기 입력에 NUL을 개행 문자가 아닌 레코드(줄) 구분 기호로 처리하도록 sed -z지시하는 것입니다 . sed그러나 텍스트 파일에는 일반적으로 NUL 문자가 포함되어 있지 않으므로 실제로 이는 sed전체 파일을 읽고 한 줄로 처리해야 함을 의미합니다. 당신은 분명히 이것을 이해합니다. 's/.*/[&]/'전체 파일을 한 줄로 처리하기를 원하지 않는 한 "전체 파일을 대괄호로 묶으십시오"라는 명령은 의미가 없습니다.

그렇다면 대용량 파일이 너무 커서 한 줄로 처리할 수 없다는 사실에 왜 그렇게 놀라셨나요?

당신은 스크립트가 때때로 작동한다고 말했습니다. 아마도 파일 크기가 다음과 같을 때입니다 sed. 이 스크립트는 파일 크기에 관계없이 동일한 작업을 수행해야 합니다.

cat "$FILE" | sed -e 's/.*/"&",/' -e '1s/^/[/' -e '$s/$/]/' | tr --delete '\n'

물론 누군가가 이렇게 하면 여전히 숨이 막힐 것이다.철사입력 내용이 너무 깁니다.

노트:

  • {그럴 필요는 없습니다 }. "$FILE"괜찮습니다.
  • 다음과 같은Steeldriver의 제안, [첫 번째 줄의 시작 부분에 a를 삽입하고 ]마지막 줄의 끝에 a를 추가합니다.
  • sponge설명의 편의를 위해 생략했습니다. 입력 파일을 덮어쓰는 것은 운영상 필요할 수 있지만 디버깅 중에 그렇게 하는 것은 나쁜 일입니다. sponge명령이 원하는 대로 수행되고 있다고 확신하면 다시 추가하십시오.

이렇게 하면 스크립트가 복제되므로 다음을 입력하세요.

The quick brown fox
jumps over
the lazy dog.

다음과 같은 결과가 생성됩니다

["The quick brown fox","jumps over","the lazy dog.",]

앞에 쉼표를 추가하세요 ]. 당신이 정말로 원하는 것이 그것이라면 전 괜찮습니다. 끝에 쉼표를 추가하지 않으려면 다음을 수행하십시오.

cat "$FILE" | sed -e 's/.*/"&",/' -e '1s/^/[/' -e '$s/,$/]/' | tr --delete '\n'

명령 '$s/,$/]/'이 추가됩니다 ].

또한 지금까지 논의된 모든 명령은 줄 바꿈 없이 파일을 남깁니다. 결국 한 명도 없었어요.  이것은 잘못된 텍스트 파일이며 일부 명령은 이를 올바르게 처리할 수 없습니다. 당신이 정말로 원하는 것이 그것이라면 전 괜찮습니다. 그렇지 않으면 추가하십시오.

echo >> "$FILE"

또는

printf '\n' >> "$FILE"

스크립트 끝에.

답변2

sed가 필요하지 않은 경우 awk로 트릭을 수행할 수 있습니다. IMHO는 좀 더 명확합니다.

편집: 원래 방법(G-Man, tnx에 의해 수정됨), 마지막 문자열 뒤에 쉼표가 있는 Q의 출력 예를 보고 이를 기반으로 했습니다.

 awk <"$FILE" -vORS= -vq=\" 'BEGIN{print "["} {print q $0 q ","} END{print "]\n"}' | sponge "$FILE"
  • G-Man이 말했듯 sponge이 디버깅 부분을 유지하십시오
  • 끝에 개행 문자를 원하지 않으면 생략하십시오.\n

추가됨: 마지막 쉼표를 제거하고 요청에 따라 괄호를 추가하도록 메서드를 수정합니다.

 awk <"$FILE" -vORS= -vq=\" 'BEGIN{print "["} {print sep q $0 q; sep=","} END{print "]\n"}' | sponge "$FILE"

(awk에서 문자열 컨텍스트의 초기화되지 않은 변수는 빈 문자열을 생성하는 것이 보장되지만 초기화하기 위해 -vsep=옵션이나 블록에 명시적으로 추가하려는 경우 );sep=""BEGIN

관련 정보