큰 파일의 시작과 끝 부분에 줄을 추가하는 시나리오가 있습니다.
아래 그림과 같이 시도해 보았습니다.
첫 번째 줄의 경우:
sed -i '1i\'"$FirstLine" $Filename
마지막 줄의 경우:
sed -i '$ a\'"$Lastline" $Filename
그러나 이 명령의 문제점은 파일의 첫 번째 줄을 추가하고 전체 파일을 반복한다는 것입니다. 마지막 줄의 경우 전체 파일을 다시 살펴보고 마지막 줄을 추가합니다. 파일 용량이 매우 커서(14GB) 시간이 오래 걸립니다.
파일을 한 번만 읽으면서 파일 시작 부분에 한 줄을 추가하고 파일 끝 부분에 다른 줄을 추가하려면 어떻게 해야 합니까?
답변1
sed -i
임시 파일을 사용하는 것은 구현 세부 사항입니다. 그러나 기존 콘텐츠를 덮어쓰지 않고 데이터 스트림의 시작 부분에 데이터를 추가하려면 피하더라도 파일을 다시 작성해야 합니다 sed -i
.
파일을 다시 쓸 수 없는 경우 파일을 읽을 때 해당 파일에 대한 작업을 고려할 수 있습니다. 예를 들면 다음과 같습니다.
{ echo some prepended text ; cat file ; } | command
또한 sed는 스트림 편집용입니다. 파일은 스트림이 아닙니다. ed 또는 ex와 같이 이러한 목적으로 설계된 프로그램을 사용하십시오. sed 옵션은 -i
이식할 수 없을 뿐만 아니라 실제로 파일을 삭제하고 다시 생성하므로 파일에 대한 모든 심볼릭 링크를 끊습니다. 이는 의미가 없습니다.
다음과 같이 단일 명령을 사용하여 이 작업을 수행할 수 있습니다 ed
.
ed -s file << 'EOF'
0a
prepend these lines
to the beginning
.
$a
append these lines
to the end
.
w
EOF
ed 구현에 따라 페이징 파일을 사용할 수 있으므로 최소한 그만큼의 여유 공간이 필요합니다.
답변2
디스크에 파일의 전체 복사본을 할당하지 않으려면 다음을 수행할 수 있습니다.
sed '
1i\
begin
$a\
end' < file 1<> file
이는 stdin/stdout이 파일일 때 sed
블록 단위로 읽고 쓰기가 수행된다는 사실을 활용합니다. 따라서 여기서 추가하는 첫 번째 줄이 블록 크기(4k 또는 8k 정도여야 함)보다 작으면 sed
읽고 있는 파일을 덮어쓸 수 있습니다.
어떤 이유로든 실패 하면 sed
(종료, 컴퓨터 충돌 등) 파일의 절반이 처리됩니다. 즉, 첫 번째 행 크기의 일부 데이터가 중간 어딘가에서 손실된다는 의미입니다.
sed
또한 이는 GNU가 아닌 이상 바이너리 데이터에서는 작동하지 않는다는 점에 유의하세요 sed
(그러나 sed를 사용하고 있으므로 -i
GNU sed를 사용하고 있는 것입니다).
답변3
다음은 몇 가지 옵션입니다(모두 파일의 새 복사본을 생성하므로 충분한 공간이 있는지 확인하세요).
간단한 에코/고양이
echo "first" > new_file; cat $File >> new_file; \ echo "last" >> new_file;
멍/멍멍 등등
gawk 'BEGIN{print "first\n"}{print}END{print "last\n"}' $File > NewFile
awk
그리고 이에 상응하는 것은 파일을 한 줄씩 읽습니다. 이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와 동일합니다.
답변4
Ex 모드에서 Vim을 사용할 수 있습니다:
ex -sc '1i|ALFA' -c '$a|BRAVO' -cx file
1
첫 번째 행 선택i
텍스트 및 줄 바꿈 삽입$
마지막 행 선택a
텍스트 및 줄 바꿈 추가x
저장하고 닫습니다