Como anexar várias linhas a um arquivo

301

Estou escrevendo um script bash para procurar um arquivo, se ele não existir, crie-o e acrescente-o:

Host localhost
    ForwardAgent yes

Então "line then new line 'tab' then text"eu acho que é um formato sensível. Eu sei que você pode fazer isso:

cat temp.txt >> data.txt

Mas parece estranho desde suas duas linhas. Existe uma maneira de acrescentar isso neste formato:

echo "hello" >> greetings.txt
A lenda
fonte

Respostas:

526
# possibility 1:
echo "line 1" >> greetings.txt
echo "line 2" >> greetings.txt

# possibility 2:
echo "line 1
line 2" >> greetings.txt

# possibility 3:
cat <<EOT >> greetings.txt
line 1
line 2
EOT

Se o sudo (outros privilégios de usuário) for necessário para gravar no arquivo, use o seguinte:

# possibility 1:
echo "line 1" | sudo tee -a greetings.txt > /dev/null

# possibility 3:
sudo tee -a greetings.txt > /dev/null <<EOT
line 1
line 2
EOT
Hauke ​​Laging
fonte
2
@ TheLegend Isso é chamado de "documento aqui". Veja esse parágrafo na página de manual.
Hauke ​​Laging
1
Mais uma possibilidade é ( echo "line 1" ; echo "line 2" ) >>greetings.txt.
27--13
2
@ ott-- Você não precisa de um subshell real (ou seja, pode salvar um novo processo), isso é suficiente:{ echo "line 1" ; echo "line 2"; } >>greetings.txt
Hauke Laging
2
Qual a diferença entre EOT e EOL?
precisa saber é
15
@cikatomo Em cat <<EOTo EOTé apenas uma seqüência aleatória. Poderia ser cat <<FOOtambém.
Hauke ​​Laging
60
printf '%s\n    %s\n' 'Host localhost' 'ForwardAgent yes' >> file.txt

Ou, se você deseja uma guia literal (em vez dos quatro espaços da sua pergunta):

printf '%s\n\t%s\n' 'Host localhost' 'ForwardAgent yes' >> file.txt

Você pode obter o mesmo efeito com echo, mas exatamente como varia de implementação para implementação, enquanto printfé constante.

evilsoup
fonte
33
echo -e "Hello \nWorld \n" >> greetings.txt
kendotwill
fonte
16

Outra abordagem é usar tee

tee -a ~/.ssh/config << END
Host localhost
  ForwardAgent yes
END

Algumas linhas de escolha da teepágina do manual:

O utilitário tee copia a entrada padrão para a saída padrão, fazendo uma cópia em zero ou mais arquivos.

-a - Anexa a saída aos arquivos em vez de substituí-los.


fonte
6

O SED pode anexar uma linha ao final de um arquivo da seguinte forma:

sed -i '$ a text to be inserted' fileName.file
$seleciona o final do arquivo, o adiz para anexar e, depois disso, vem o texto a ser inserido. Então, é claro, o nome do arquivo.


Fonte: http://www.yourownlinux.com/2015/04/sed-command-in-linux-append-and-insert-lines-to-file.html

========== EDIT == ==========

Essa abordagem tem algum benefício adicional do que outras soluções?
Sim, essa abordagem tem o benefício adicional de anexar a qualquer arquivo retornado em uma pesquisa, como esta: find . -name "*.html" -exec sed -i '$ a </html>' {} \;

Usei o exemplo acima para inserir a tag html final que faltava em todas as páginas html em vários diretórios.

===================================

OB7DEV
fonte
1
Se você mostrasse a sintaxe para anexar várias linhas a um arquivo, isso seria uma resposta para a pergunta (embora não seja muito útil). Todas as outras respostas simplesmente escrevem o novo texto. Esta resposta lê o arquivo inteiro e o reescreve, além do texto adicionado. Essa abordagem tem algum benefício sobre as outras?
G-Man
Isso funciona apenas com o GNU sed. BSD sedafiança com o erro: command a expects \ followed by text. Portanto, não use isso para uma solução com script; é susceptível de quebrar. (Ou fazê-lo corretamente como o BSD exigido sintaxe é POSIX compatível e vai trabalhar em GNU sedtambém.
Wildcard
As outras respostas pode ser usado com findo seguinte: find . -name "*.txt" -exec sh -c 'printf "%s\n\t%s\n" "Host localhost" "ForwardAgent yes" >> "$1"' sh {} ";".
G-Man
1
Essa é uma solução muito boa, pois não faz o redirecionamento de fluxo ( >, >>) e, portanto, não sofre de problemas como execução sudo echo 'something' > /file. Para mim é perfeitamente permite anexar uma linha em um arquivo no recipiente LXD assim: lxc exec c sed -- '$ a newline' /myfile.
Draco Ater
O echo "a new line" >> foo.filenão criará uma nova linha quando o arquivo não estiver no final da nova linha, mas o sed -i '$ a a new line' foo.filefará, então sedé melhor, especialmente se você quiser sempre acrescentar uma nova linha ao arquivo.
Zhouji 12/09/16
1

Eu usei o sed porque ele pode ser usado com o sudo. Por exemplo:

sudo sed -i '$ a text to be inserted' fileName.file 

a alternativa é muito feia como:

sudo bash -c "echo a text to be inserted >> fileName.file"  

e ainda mais feio quando feito com ssh.

Fred Mehrdad
fonte
1
Por que essa resposta foi reduzida? Parece a solução que eu preciso. Existe algum problema com isso? Se não, eu vou usá-lo e votá-lo.
MountainX
Você sed -inão usa uma extensão como argumento? Seu exemplo pode ter parâmetros incorretos.
Protometa
1

Outro liner é:

echo "Greetings 1" >> greetings.txt && echo "Greetings 2" >> greetings.txt

Eu preferiria a -eopção pensada, pois oferece mais controle:

echo -e "Greeting 1\nGreetings 2\n" >> greetings.txt
Erdal G.
fonte
1

Pode-se emular cat >> out.txtcom Perl ou Python para obter o mesmo efeito. Perl:

perl -e 'open(fh,">>","./out.txt");while(<>){printf(fh "%s",$_)};close(fh);'

E Python:

python -c 'import sys;f=open(sys.argv[1],"a");l=[i for i in sys.stdin];f.write("".join(l))' out.txt 

Observe que, para python, você terá que pressionar Ctrl+ Dduas vezes. Consulte a pergunta relacionada no stackoverflow para obter mais informações.

Sergiy Kolodyazhnyy
fonte
1

Aqui está um exemplo para anexar várias linhas em um arquivo:

{
        echo '  directory "/var/cache/bind";'
        echo '  listen-on { 127.0.0.1; };'
        echo '  listen-on-v6 { none; };'
        echo '  version "";'
        echo '  auth-nxdomain no;'
        echo '  forward only;'  
        echo '  forwarders { 8.8.8.8; 8.8.4.4; };'
        echo '  dnssec-enable no;'
        echo '  dnssec-validation no;'
} >> your_file.txt
user2753331
fonte
0

Além da resposta principal, caso o arquivo precise de permissões de superusuário, apenas adicionar sudona frente echonão funcionará.

Isso ocorre porque o shell quebra os comandos e, embora echotenha sido executado como root, mas >>executado com privilégios normais.

Isso funcionará para o superusuário: sudo su -c "echo 'Line 3' >> greetings.txt"

SJ00
fonte
Você não precisa do suaqui ( sudo sunão é bom). Mas você está certo de que precisa de algo para gerenciar o redirecionamento do shell; talvez sudo sh -c "echo stuff >> file.txt". Sem economia de rede, mas uma prática melhor.
roaima 8/08