매우 큰 파일에서 텍스트를 빠르게 교체


25

25GB 텍스트 파일이있어 몇 줄로만 문자열을 교체해야합니다. sed성공적으로 사용할 수 있지만 실행하는 데 시간이 오래 걸립니다.

sed -i 's|old text|new text|g' gigantic_file.sql

더 빠른 방법이 있습니까?


바꿀 텍스트가있는 줄 번호를 알고 있습니까? 속도를 높이기위한 유일한 옵션이 아니라면 더 빠른 컴퓨터를 얻는 것입니다. 많은 양의 데이터가 있다는 사실은 데이터를 검색하는 데 많은 시간이 걸립니다.
David King

줄 번호를 아주 빨리 잡을 수 있습니다. 그렇습니다.
eisaacson

- 당신은 또한 속도를 높이기 위해 여러 개의 CPU 코어를 사용할 수 있습니다 rankfocus.com/use-cpu-cores-linux-commands
ahaswer

큰 파일에는 sed를 사용하지 마십시오. 에서 봐 VI 또는 정력 대신.
MikeJRamsey56

답변:


26

당신은 시도 할 수 있습니다:

sed -i '/old text/ s//new text/g' gigantic_file.sql

심판에서 :

속도 최적화 : 큰 입력 파일이나 느린 프로세서 또는 하드 디스크로 인해 실행 속도를 높여야하는 경우 "s /.../를주기 전에"찾기 "식을 지정하면 대체가 더 빨리 실행됩니다. ../ "명령.

다음은 10G 파일을 비교 한 것입니다. 전에:

$ time sed -i 's/original/ketan/g' wiki10gb
real    5m14.823s
user    1m42.732s
sys     1m51.123s

후:

$ time sed -i '/ketan/ s//original/g' wiki10gb
real    4m33.141s
user    1m20.940s
sys     1m44.451s

마지막 sed철자가 잘못되었습니다. 나는 마지막으로 수정 어제이 기사를 편집 sed해야 명령 time sed -i '/original/ s//ketan/g' wiki10gb하지를 time sed -i '/ketan/ s//original/g' wiki10gb. 1. 시간이 더 이상 명령과 일치하지 않고 2 + 3GB 파일에서 GNU sed로 동일한 테스트를 수행했으며 두 sed대안 사이의 차이점을 관찰하지 못하기 때문에 오늘 편집 내용을 되돌 립니다. 시간의 차이는 철자가 틀린 것 같습니다.
xhienne

@xhienne 철자가 틀렸다는 것이 무슨 뜻인지 잘 모르겠습니다. 첫 번째 실행에서 '원본'이라는 단어를 'ketan'으로 대체하고 두 번째 실행에서 'ketan'이라는 용어를 '원본'이라는 용어로 대체하여 두 경우 모두 동일한 수의 대체를 얻습니다.
mkc

1
평판이 좋지 않은 새 사용자가보고 한 "수정"을 적용하고있었습니다. 이제 당신이 한 일을 이해합니다. 그러나 한 구문이 다른 구문보다 낫다는 것을 증명하려면 여기서는 그렇지 않은 것과 동일한 작업을 수행해야합니다 (CPU 측면에서 5-char 문자열을 찾는 것은 a를 찾는 것과 같지 않습니다). 7 자 문자열). 또한 10GB 파일에 대한 이러한 종류의 테스트는 시스템로드 (CPU, 디스크)에 따라 크게 달라집니다. 나는 time개인적으로 결과 에서 많은 변동을 보았지만 결국에는 시간의 차이가 없었습니다.
xhienne

여기 허용 대답을 참조 -이 관련되어 생각 stackoverflow.com/questions/11145270/...를 내 경우 : 나오지 스트림 >> 전체 파일을하지만, 줄 번호를 (알려진 경우) 지정이 답변에서 언급 한 바와 같이 도움 실행 속도가 2 ~ 2 배 증가했습니다 (GNU sed 4.5). 패턴 검색을 기반으로 grep -n 또는 ripgrep (rg)를 사용하여 행 번호를 찾을 수 있습니다. 실제로 행 번호를 지정하는 것은 위의 답변에 따라 해당 파일에서 검색 결과를 얻는 것과 같습니다.
Victoria Stuart

1

짧은 대답은 "아니오"입니다. 이러한 종류의 작업에 대한 제한 요소는 디스크 IO입니다. 25GB의 디스크를 더 빠르게 스트리밍 할 수있는 방법이 없습니다. 제자리에 편집하지 않으면 약간의 개선이있을 수 있으며 결과를 sed별도의 드라이브에 씁니다 (사용 가능한 경우). 다른 방식으로 쓰거나 약간 쓰는 동안 하나에서 읽을 수 있기 때문입니다. 결과적으로 적은 경합.

각 줄에 정규식 엔진을 사용하지 않으면 속도를 높일 수 있습니다 -예를 들어 perl을 사용하십시오 (이 작업을 수행 할 수는 sed있지만 구문을 모릅니다)-시작부터 10,000 줄 이상.

perl -pe '$. > 10_000 && s/old_text/new_text/g' 

그리고 RE (메타 문자)에 어떤 종류의 합병증이있는 경우이를 최소화 하면 정규식 엔진의 효율성 이 약간 향상 됩니다 .


1
sed에서sed -i '10000,$ s/old_text/new_text/g'
Dani_l

아름다운. sed비교 방법을 모르겠습니다 . 파일 크기 때문에 조금 더 빠르다고 가정합니다.
Sobrique

나는 perl이 sed보다 빠르다고 가정하지만 sed는 다소 덜 암호 적이거나 오히려 초기 학습 곡선이 덜 필요합니다.
Dani_l

1
지금 말한 것, 반대를 참조하십시오 - 당신이 (거의) 쓸 수 sed있는 perl, 그러나 후자는 또한 당신이 너무 스크립트 자세한 더 작성할 수 있습니다.
Sobrique

0

새 텍스트와 기존 텍스트의 길이가 같은 경우 전체 파일을 복사하는 대신 파일을 찾아서 변경된 바이트 만 쓸 수 있습니다. 그렇지 않으면 많은 양의 데이터가 이동 될 수 있습니다.

참고 : 이것은 까다 롭고 사용자 정의 코드 작성과 관련이 있습니다.

C 또는 C ++로 작업하고 있거나 검색 및 쓰기 시스템 호출을 위해 선호하는 언어 래퍼 인 경우 fseek 맨 페이지를 참조하십시오.

명령 행 만 사용하고 텍스트의 바이트 오프셋을 얻을 수있는 경우 신중하게 작성된 "dd"명령으로 대체 텍스트를 작성할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.