거대한 파일의 시작과 끝에 줄을 추가하는 시나리오가 있습니다.
아래에 표시된 것처럼 시도했습니다.
-
첫 줄 :
sed -i '1i\'"$FirstLine" $Filename
-
마지막 줄 :
sed -i '$ a\'"$Lastline" $Filename
그러나이 명령의 문제점은 파일의 첫 번째 행을 추가하고 전체 파일을 순회한다는 것입니다. 마지막 줄의 경우 전체 파일을 다시 탐색하고 마지막 줄을 추가합니다. 매우 큰 파일 (14GB) 이후 시간이 오래 걸립니다.
파일을 한 번만 읽는 동안 파일의 시작 부분과 끝 부분에 줄을 추가하려면 어떻게해야합니까?
답변
sed -i
tempfile을 구현 세부 사항으로 사용합니다. 그러나 기존 내용을 덮어 쓰지 않고 데이터 스트림의 시작 부분에 데이터를 추가하려면 파일을 다시 써야합니다 sed -i
.
파일 재 작성이 옵션이 아닌 경우 파일을 읽을 때 조작하는 것을 고려할 수 있습니다 (예 :
{ echo some prepended text ; cat file ; } | command
또한 sed는 스트림을 편집하기위한 것입니다. 파일은 스트림이 아닙니다. ed 또는 ex와 같이이 목적을위한 프로그램을 사용하십시오. -i
sed에 대한 옵션은 이식 가능할뿐만 아니라 파일에 대한 심볼릭 링크도 끊습니다. 파일을 삭제하고 다시 생성하기 때문에 무의미합니다.
다음과 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 …) 파일이 절반으로 처리되어 중간에 누락 된 첫 번째 줄의 크기를 의미합니다.
또한 sed
GNU sed
가 아닌 경우 이진 데이터에는 작동하지 않습니다 (그러나 사용하기 때문에 -i
GNU 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
첫 줄을 선택하십시오 -
i
텍스트와 개행 삽입 -
$
마지막 줄을 선택하십시오 -
a
텍스트와 개행 추가 -
x
저장하고 닫습니다
답변
파일 시작 부분에 데이터를 삽입 할 수있는 방법 ¹이 없습니다. 새 파일을 만들고 추가 데이터를 작성하고 이전 데이터를 추가하기 만하면됩니다. 따라서 첫 번째 줄을 삽입하려면 전체 파일을 한 번 이상 다시 작성해야합니다. 그러나 파일을 다시 쓰지 않고 마지막 줄을 추가 할 수 있습니다.
sed -i '1i\'"$FirstLine" $Filename
echo "$LastLine" >>$Filename
또는 두 개의 명령을 한 번의 sed 실행에 결합 할 수 있습니다.
sed -i -e '1i\'"$FirstLine" -e '$ a\'"$Lastline" $Filename
sed -i
새 출력 파일을 만든 다음 이전 파일 위로 옮깁니다. 이것은 sed가 작동하는 동안 공간을 차지하는 두 번째 파일 사본이 있음을 의미합니다. 파일을 제자리 에 덮어 써서 이것을 피할 수 있지만 주요 제한 사항이 있습니다. 추가하는 행이 sed의 버퍼보다 작아야합니다. 시스템이 충돌하면 파일이 손상되고 일부 내용이 손실됩니다. 중간에 있으므로 강력히 권장합니다.
¹ Linux에는 파일에 데이터를 삽입 할 수있는 방법이 있지만 전체 파일 시스템 블록 만 삽입 할 수 있으며 임의 길이의 문자열을 삽입 할 수 없습니다. 데이터베이스 및 가상 시스템과 같은 일부 응용 프로그램에는 유용하지만 텍스트 파일에는 유용하지 않습니다.
답변
$ (echo "Some Text" ; cat file1) > file2