Bash - 텍스트 파일을 모두 읽지 않고 텍스트 파일의 시작 부분에 문자열을 추가하려면 어떻게 해야 합니까?

Bash - 텍스트 파일을 모두 읽지 않고 텍스트 파일의 시작 부분에 문자열을 추가하려면 어떻게 해야 합니까?

"test.txt"라는 텍스트 파일 앞에 "hello world"라는 문자열을 삽입하려고 합니다. 이미 sed로 수행하고 있지만 불행히도 "sed 명령"은 전체 파일을 읽기 때문에 메모리를 죽입니다.

내 파일에는 1GB 크기의 텍스트가 포함되어 있고 내 메모리는 512MB에 불과합니다. 어떻게 할 수 있나요? 다음과 같습니다.

echo --insert-before "hello world" >> test.txt

또는 이전에 삽입하기 위해 사용해야 하는 연산자는 다음과 같습니다.

echo "hello world" << test.txt

아니면 다른 아이디어인가요?

참고: 끝에 텍스트를 삽입하는 연산자는 >>잘 작동합니다. 메모리를 죽이지는 않지만 파일 시작 시 역순으로 수행해야 하며 새 줄 없이 텍스트 파일의 내용을 재정의하지 않고 수행해야 합니다.

내가 사용한 실제 코드는 다음과 같습니다.

echo "hello world" > test.txt;
echo "the large content that size is 1gb" >> test.txt;
sed -i ':a;N;$!ba;s/\n//g' test.txt;

답변1

사용한 명령 순서는 다음과 같습니다.

echo "hello world" > test.txt;
echo "the large content that size is 1gb" >> test.txt;
sed -i ':a;N;$!ba;s/\n//g' test.txt;

명령이 실제로 다음과 같다고 가정하겠습니다.

echo "hello world" > newfile;
cat test.txt >> newfile;            # assuming the file with 1GigaByte was test.txt

그리고 당신은 (설명에서) 개행 문자를 제거하기 위해서만 존재하는 sed 명령에 대해 불만을 제기합니다.

tr(많은) 메모리를 사용하지 않는 경우 에도 동일한 작업을 수행할 수 있습니다 .

echo "hello world" > newfile;
cat test.txt | tr -d '\n' >> newfile

그리고 newfile앞에 "hello world"가 붙은 test.txt 복사본이 있습니다.

답변2

sed메모리를 많이 사용하지 않습니다. 그러나 OS가 디스크를 캐싱할 수 있습니다. 따라서 를 사용하면 nocache도움이 될 수 있습니다(디스크가 충분히 빠르거나 동일한 데이터를 두 번 이상 읽지 않는 경우). 그리고/또는 --unbuffered다음 옵션을 사용하십시오 sed(그러므로 sed의존은 가능한 한 적은 메모리를 사용합니다).

>>또한 명령이 아닌 쉘에 의해 수행되는 것처럼 에코에 대한 옵션이 있을 수 없습니다 . 이는 명령의 표준 출력을 파일에 추가하도록 쉘에 지시합니다.

그리고 @Kusalananda가 말했듯이 귀하의 sed스크립트는 효율적이지 않습니다. 나는 아마도 고양이를 사용할 것입니다.

uncache cat "<(echo the_prefix)" old_file_name > new_file_name
rm old_file_name
mv -T new_file_name old_file_name #note not all `mv`s have the `-T` option, it can unsafely be left out.

답변3

좀 더 간단한 건 어때요?

cat <<_eof_ > file
Hello world!
$(cat file)
_eof_

아니면 에드를 사용하세요

echo '0a
your text here
.
w' | ed some_file

답변4

이것이 당신의 기억을 죽이고 있다면:

sed -i ':a;N;$!ba;s/\n//g' "test.txt"

그런 다음 줄 바꿈을 제거하고 한 번에 하나만 읽으려면 다음을 시도하십시오.

{
    printf "hello world"  # with no newline
    while IFS= read -r line || [ -n "$line" ]; do
        printf "%s" "$line"
    done < test.txt
    echo ""          # add a newline to the end of the file
} > test.txt.tmp && mv test.txt{.tmp,}

일반적인 상황에서는 sed보다 약간 느리지만 상황은 평범하지 않습니다.

관련 정보