
estou tentando inserir uma string "hello world" antes de um arquivo de texto chamado "test.txt", já faço isso com sed, mas infelizmente o "comando sed" mata minha memória, pois lê um arquivo inteiro.
meu arquivo contém um texto com tamanho de 1gb e minha memória tem apenas 512 mb. como posso fazer isso?, algo assim:
echo --insert-before "hello world" >> test.txt
Ou qual operador devo usar para inseri-lo antes, algo assim:
echo "hello world" << test.txt
Ou outra ideia?
Obs: o operador >>
para inserir texto no final funciona bem, não mata minha memória, mas preciso fazer ao contrário para iniciar o arquivo, sem substituir o conteúdo do meu arquivo de texto, sem nova linha.
aqui está o meu código real que usei:
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;
Responder1
Você afirma que a sequência de comandos que você usou foi:
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;
Presumirei que os comandos eram na verdade:
echo "hello world" > newfile;
cat test.txt >> newfile; # assuming the file with 1GigaByte was test.txt
E você reclama do comando sed, que existe apenas para remover novas linhas (da sua descrição).
O mesmo poderia ser feito com tr
o qual não usa (muita) memória:
echo "hello world" > newfile;
cat test.txt | tr -d '\n' >> newfile
E newfile
terá uma cópia do test.txt com "hello world" anexado.
Responder2
sed
não usa muita memória. No entanto, o sistema operacional pode estar armazenando em cache o disco. Portanto, usar nocache
pode ajudar (se o disco for rápido o suficiente ou se você não estiver lendo os mesmos dados mais de uma vez). E/ou use a --unbuffered
opção de sed
(para que sed
a confiança use o mínimo de memória possível).
Além disso, não pode haver opção de eco, como >>
é feito pelo shell, não pelo comando. Diz ao shell para anexar o stdout do comando ao arquivo.
E como diz @Kusalananda, seu sed
script não é eficiente. Eu provavelmente usaria apenas 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.
Responder3
Que tal algo um pouco mais simples?
cat <<_eof_ > file
Hello world!
$(cat file)
_eof_
Ou use ed
echo '0a
your text here
.
w' | ed some_file
Responder4
Se isso está matando sua memória:
sed -i ':a;N;$!ba;s/\n//g' "test.txt"
então, para remover novas linhas, mas ler apenas uma de cada vez, tente:
{
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,}
Isso será um pouco mais lento que o sed, em circunstâncias normais, mas sua situação está fora do comum.