
Я пытаюсь вставить строку «hello world» перед текстовым файлом с именем «test.txt». Я уже делаю это с помощью sed, но, к сожалению, «команда sed» убивает мою память, потому что она считывает весь файл.
Мой файл содержит текст размером 1 ГБ, а памяти у меня всего 512 МБ. Как мне это сделать?, что-то вроде этого:
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
будет иметь копию test.txt с добавленным в начало "hello world".
решение2
sed
не использует много памяти. Однако ОС может кэшировать диск. Поэтому использование nocache
может помочь (если диск достаточно быстрый или вы не считываете одни и те же данные более одного раза). И/или используйте опцию --unbuffered
( sed
чтобы sed
Reli использовал как можно меньше памяти).
Также не может быть опции echo, как >>
это делает оболочка, а не команда. Она сообщает оболочке, что нужно добавить stdout команды в файл.
И как говорит @Kusalananda, ваш sed
скрипт неэффективен. Я бы, наверное, просто использовал cat.
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_
Или используйте ed
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, но ваша ситуация нестандартная.