거대한 파일의 시작과 끝에 줄 추가 $Filename 마지막 줄 : sed -i

거대한 파일의 시작과 끝에 줄을 추가하는 시나리오가 있습니다.

아래에 표시된 것처럼 시도했습니다.

  • 첫 줄 :

    sed -i '1i\'"$FirstLine" $Filename
  • 마지막 줄 :

    sed -i '$ a\'"$Lastline" $Filename  

그러나이 명령의 문제점은 파일의 첫 번째 행을 추가하고 전체 파일을 순회한다는 것입니다. 마지막 줄의 경우 전체 파일을 다시 탐색하고 마지막 줄을 추가합니다. 매우 큰 파일 (14GB) 이후 시간이 오래 걸립니다.

파일을 한 번만 읽는 동안 파일의 시작 부분과 끝 부분에 줄을 추가하려면 어떻게해야합니까?



답변

sed -itempfile을 구현 세부 사항으로 사용합니다. 그러나 기존 내용을 덮어 쓰지 않고 데이터 스트림의 시작 부분에 데이터를 추가하려면 파일을 다시 써야합니다 sed -i.

파일 재 작성이 옵션이 아닌 경우 파일을 읽을 때 조작하는 것을 고려할 수 있습니다 (예 :

{ echo some prepended text ; cat file ; } | command

또한 sed는 스트림을 편집하기위한 것입니다. 파일은 스트림이 아닙니다. ed 또는 ex와 같이이 목적을위한 프로그램을 사용하십시오. -ised에 대한 옵션은 이식 가능할뿐만 아니라 파일에 대한 심볼릭 링크도 끊습니다. 파일을 삭제하고 다시 생성하기 때문에 무의미합니다.

다음과 ed같이 단일 명령으로이 작업을 수행 할 수 있습니다 .

ed -s file << 'EOF'
0a
prepend these lines
to the beginning
.
$a
append these lines
to the end
.
w
EOF

ed의 구현에 따라 페이징 파일을 사용할 수 있으므로 최소한 사용 가능한 공간이 있어야합니다.


답변

디스크에 파일의 전체 사본을 할당하지 않으려면 다음을 수행하십시오.

sed '
1i\
begin
$a\
end' < file 1<> file

그것은 stdin / stdout이 파일 일 때 sed 블록별로 읽고 쓰는 사실을 사용합니다 . 따라서 여기에서 추가하는 첫 번째 줄이 sed블록 크기 보다 작은 한 (4k 또는 8k와 같아야 함 ) 읽고있는 파일을 무시해도됩니다 .

어떤 이유로 든 sed실패하면 (killed, machine crash …) 파일이 절반으로 처리되어 중간에 누락 된 첫 번째 줄의 크기를 의미합니다.

또한 sedGNU sed가 아닌 경우 이진 데이터에는 작동하지 않습니다 (그러나 사용하기 때문에 -iGNU sed를 사용하고 있음).


답변

다음은 몇 가지 선택 사항입니다 (모두 파일의 새 사본을 작성하므로 충분한 공간이 있는지 확인하십시오).

  • 간단한 에코 / 고양이

    echo "first" > new_file; cat $File >> new_file; \
      echo "last" >> new_file; 
  • awk / gawk 등

    gawk 'BEGIN{print "first\n"}{print}END{print "last\n"}' $File > NewFile 

    awk그리고 ilk는 파일을 한 줄씩 읽습니다. BEGIN{}블록은 첫 번째 행과 전에 실행되는 END{}마지막 라인 이후 블록. 따라서 위의 명령은을 의미 print "first" at the beginning, then print every line in the file and print "last" at the end합니다.

  • perl -ne 'BEGIN{print "first\n"} print;END{print "last\n"}' $File > NewFile

    이것은 본질적으로 Perl로 작성된 위의 gawk와 동일합니다.


답변

나는 훨씬 간단한 것을 선호합니다.

gsed -i '1s/^/foo\n/gm; $s/$/\nbar/gm' filename.txt

파일을 변환합니다.

asdf
qwer

파일에 :

foo
asdf
qwer
bar

답변

Ex 모드에서 Vim을 사용할 수 있습니다 :

ex -sc '1i|ALFA' -c '$a|BRAVO' -cx file
  1. 1 첫 줄을 선택하십시오

  2. i 텍스트와 개행 삽입

  3. $ 마지막 줄을 선택하십시오

  4. a 텍스트와 개행 추가

  5. x 저장하고 닫습니다


답변

파일 시작 부분에 데이터를 삽입 할 수있는 방법 ¹이 없습니다. 새 파일을 만들고 추가 데이터를 작성하고 이전 데이터를 추가하기 만하면됩니다. 따라서 첫 번째 줄을 삽입하려면 전체 파일을 한 번 이상 다시 작성해야합니다. 그러나 파일을 다시 쓰지 않고 마지막 줄을 추가 할 수 있습니다.

sed -i '1i\'"$FirstLine" $Filename
echo "$LastLine" >>$Filename

또는 두 개의 명령을 한 번의 sed 실행에 결합 할 수 있습니다.

sed -i -e '1i\'"$FirstLine" -e '$ a\'"$Lastline" $Filename

sed -i새 출력 파일을 만든 다음 이전 파일 위로 옮깁니다. 이것은 sed가 작동하는 동안 공간을 차지하는 두 번째 파일 사본이 있음을 의미합니다. 파일을 제자리덮어 써서 이것을 피할 수 있지만 주요 제한 사항이 있습니다. 추가하는 행이 sed의 버퍼보다 ​​작아야합니다. 시스템이 충돌하면 파일이 손상되고 일부 내용이 손실됩니다. 중간에 있으므로 강력히 권장합니다.

¹ Linux에는 파일에 데이터를 삽입 할 수있는 방법이 있지만 전체 파일 시스템 블록 만 삽입 할 수 있으며 임의 길이의 문자열을 삽입 할 수 없습니다. 데이터베이스 및 가상 시스템과 같은 일부 응용 프로그램에는 유용하지만 텍스트 파일에는 유용하지 않습니다.