[bash] bash / sed 스크립트를 사용하여 텍스트 파일의 첫 줄을 어떻게 제거합니까?

bash 스크립트를 사용하여 거대한 텍스트 파일에서 첫 번째 줄을 반복해서 제거해야합니다.

지금은 사용하고 sed -i -e "1d" $FILE있지만 삭제하는 데 약 1 분이 걸립니다.

이것을 달성하는 더 효율적인 방법이 있습니까?



답변

꼬리를 보십시오 :

tail -n +2 "$FILE"

-n x: 마지막 x줄만 인쇄하십시오 . tail -n 5입력의 마지막 5 줄을 줄 것입니다. +반전의 부호 종류의 인수 및 메이크업 tail인쇄 아무것도하지만 첫 번째 x-1라인. tail -n +1전체 파일을 인쇄하고tail -n +2 첫 번째 줄을 제외한 모든 것을 .

GNU tail는보다 훨씬 빠릅니다 sed. tailBSD에서도 사용할 수 있으며 -n +2플래그는 두 도구에서 일관됩니다. 자세한 내용은 FreeBSD 또는 OS X 매뉴얼 페이지를 확인하십시오 .

그러나 BSD 버전은보다 느릴 수 있습니다 sed. 그들이 어떻게 관리했는지 궁금합니다. 스크립트를 해석하고 정규 표현식을 적용하는 등의 복잡한 작업을 수행하는 tail동안 파일을 한 줄씩 읽어야합니다 sed.

참고 : 사용하고 싶을 수도 있습니다

# THIS WILL GIVE YOU AN EMPTY FILE!
tail -n +2 "$FILE" > "$FILE"

그러나 이것은 당신에게 빈 파일을 줄 것 입니다. 쉘이 재 호출 >하기 전에 재 지정 ( )이 발생하기 때문 tail입니다.

  1. 셸은 파일을 자릅니다 $FILE
  2. 쉘은 새로운 프로세스를 만듭니다 tail
  3. 쉘은 tail프로세스의 표준 출력 을$FILE
  4. tail 지금 비어있는에서 읽습니다 $FILE

파일 내부의 첫 번째 줄을 제거하려면 다음을 사용해야합니다.

tail -n +2 "$FILE" > "$FILE.tmp" && mv "$FILE.tmp" "$FILE"

&&문제가있을 때 파일이 덮어하지 않도록 할 것입니다.


답변

‘>’연산자를 사용하지 않고 -i를 사용하여 파일을 업데이트 할 수 있습니다. 다음 명령은 파일에서 첫 번째 줄을 삭제하고 파일에 저장합니다.

sed -i '1d' filename


답변

GNU 이외의 SunOS 사용자에게는 다음 코드가 도움이됩니다.

sed '1d' test.dat > tmp.dat 


답변

아니, 그것은 당신이 얻을만큼 효율적입니다. 작업을 조금 더 빠르게 할 수있는 C 프로그램을 작성할 수는 있지만 (시작 시간이 적고 인수를 처리하는 경우) 파일이 커질 때 sed와 동일한 속도로 향할 수 있습니다 (분이 걸리면 크기가 크다고 가정합니다) ).

그러나 귀하의 질문에는 솔루션을 미리 제안한다는 점에서 다른 많은 사람들과 동일한 문제가 있습니다. 당신이 세부에서 우리에게 얘기를한다면 무엇을 당신이보다는 일을하려고하고 어떻게 , 우리는 더 나은 옵션을 제안 할 수 있습니다.

예를 들어, 이것이 다른 프로그램 B가 처리하는 파일 A 인 경우 한 솔루션은 첫 번째 행을 제거하지 않고 프로그램 B를 수정하여 다르게 처리하는 것입니다.

모든 프로그램이이 파일 A에 추가되고 프로그램 B는 현재 첫 번째 행을 읽고 처리하기 전에이를 읽습니다.

프로그램 B를 다시 엔지니어링하여 첫 번째 줄을 삭제하려고 시도하지 않았지만 파일 A에 대한 영구적 인 (아마도 파일 기반) 오프셋을 유지하여 다음에 실행될 때 해당 오프셋을 찾고 프로세스를 찾을 수 있습니다. 거기에 선을 긋고 오프셋을 업데이트하십시오.

그런 다음 조용한 시간 (자정?)에서 파일 A의 특수 처리를 수행하여 현재 처리 된 모든 행을 삭제하고 오프셋을 다시 0으로 설정할 수 있습니다.

프로그램이 파일을 열고 다시 쓰는 것이 아니라 파일을 열고 찾는 것이 더 빠를 것입니다. 이 토론은 물론 프로그램 B를 제어한다고 가정합니다. 그 경우인지 모르겠지만 추가 정보를 제공하면 다른 가능한 해결책이있을 수 있습니다.


답변

파일을 제자리에서 편집 있습니다. 다음 -i과 같이 펄의 플래그를 사용 하십시오 :

perl -ni -e 'print unless $. == 1' filename.txt

요청한대로 첫 번째 줄이 사라집니다. Perl은 전체 파일을 읽고 복사해야하지만 출력이 원본 파일 이름으로 저장되도록 정렬합니다.


답변

다음과 같이 쉽게 수행 할 수 있습니다.

cat filename | sed 1d > filename_without_first_line

명령 행에서; 또는 파일의 첫 번째 행을 영구적으로 제거하려면 -i플래그 와 함께 sed의 내부 모드를 사용하십시오 .

sed -i 1d <filename>


답변

Pax가 말했듯이 아마도 이것보다 더 빠를 수는 없습니다. 그 이유는 파일 시작 부분에서 잘림을 지원하는 파일 시스템이 거의 없기 때문에 파일 크기가 O ( n) 작업 이 될 것 n입니다. 훨씬 더 빨리 할 수있는 일은 동일한 바이트 수 (공백 또는 주석이있을 수 있음)로 첫 번째 줄을 덮어 쓰는 것입니다. 실제로 수행하려는 작업에 따라 작동 할 수 있습니다 (무엇입니까?).