Caminho 1: escape instâncias de \
que você não quer escapar de outros personagens.
Com base no conteúdo da sua string, você provavelmente vai querer:
echo -e 'writes (>> appends) in note.txt this text\non 2 lines (with "-e" and "\n" help)' >> note.txt
O texto anexado a note.txt
é:
writes (>> appends) in note.txt this text
on 2 lines (with "-e" and "\n" help)
As alterações são:
- Você tinha
/n
onde parecia que você queria uma quebra de linha. Então eu mudei para\n
. - No texto
with "-e" and "\n"
, o\
deve ser impresso literalmente, em vez de combinar com on
que o segue e produzir uma nova linha. Então eu citei (escapei)\
com outro\
. Se\n
produzir uma nova linha,\n
produzirá\n
. -
Substitui as aspas duplas externas (
"
) por aspas simples ('
). Você queria que os caracteres"
em torno de-e
e\n
fossem impressos literalmente, mas terminaram e reiniciaram a cotação, impedindo que eles sejam impressos e fazendo com que\n
seja realmente impresso comon
(porque não foi marcado\n
é processado antes de ser passado paraecho
). Uma solução alternativa seria escrever\"
para os caracteres"
internos. Mas não havia nenhuma razão para incluir a coisa toda entre aspas duplas - aspas simples são geralmente preferíveis nos casos em que qualquer uma pode ser usada .A outra mudança - que não foi uma mudança no comando final, mas foi uma alteração que fiz apenas enquanto estava trabalhando nela - foi que eu removi o redirecionamento
>> note.txt
até Eu sabia que tinha o comando certo. Ao enviar a saída para o terminal, imediatamente pude ver qual era o efeito. Eu adicionei novamente o redirecionamento quando terminei.
Isso está estilisticamente mais próximo do que você já tinha, mas não é a única maneira de fazer isso.
Caminho 2: Separe os comandos echo
para linhas separadas, em vez de usar -e
.
Como a única seqüência que você deseja tratar especialmente por eco é o \n
(entre text
e on
), você pode usar apenas dois comandos echo
separados e (como muru pode estar sugerindo ) não use -e
.
Aqui estão duas maneiras de redirecionar a saída de vários comandos:
-
Dois redirecionamentos separados, um para cada comando.
echo 'writes (>> appends) in note.txt this text' >> note.txt echo 'on 2 lines (with "-e" and "\n" help)' >> note.txt
Se o nome do arquivo for longo ou se você estiver escrevendo um script e quiser apenas alterá-lo em um só lugar, poderá atribuí-lo a uma variável:
out="/home/ek/Documents/long name that can have spaces as it's quoted/note.txt" echo 'writes (>> appends) in note.txt this text' >> "$out" echo 'on 2 lines (with "-e" and "\n" help)' >> "$out"
-
Um redirecionamento único aplicado a um comando composto composto pelos dois comandos.
{ echo 'writes (>> appends) in note.txt this text' echo 'on 2 lines (with "-e" and "\n" help)' } >> note.txt
Você pode colocar isso em uma linha, se quiser, mas se não houver uma nova linha antes da chave de fechamento (
}
), um ponto-e-vírgula (;
) deve preceder:{ echo 'writes (>> appends) in note.txt this text'; echo 'on 2 lines (with "-e" and "\n" help)'; } >> note.txt
Caminho 3: passe um literal \n
para echo
em vez de usar -e
.
Linhas novas reais podem aparecer entre aspas (simples ou dupla) e são interpretadas literalmente:
echo 'writes (>> appends) in note.txt this text
on 2 lines (with "-e" and "\n" help)' >> note.txt
Como a primeira linha termina entre aspas, o shell não aceita o final do comando, mas continua lendo.
Se você quiser encaixá-lo em uma única linha, poderá usar $'\n'
, que se expande para uma nova linha. Isso é expandido pelo shell antes ser passado para o comando echo
, portanto, ele não deve ser citado.
echo 'writes (>> appends) in note.txt this text'$'\n''on 2 lines (with "-e" and "\n" help)' >> note.txt
Caminho 4: use printf
printf
é muito poderoso; Há várias maneiras de usá-lo para resolver esse problema. Como estou apresentando isso como uma solução distinta dos outros, aqui está uma boa maneira de usá-lo de uma maneira que você não pode usar echo
:
printf '%s\n%s\n' 'writes (>> appends) in note.txt this text' 'on 2 lines (with "-e" and "\n" help)' >> note.txt
A sintaxe geral para printf
é printf format args...
(onde args...
significa zero ou mais argumentos adicionais da linha de comando). A string de formato acima, %s\n%s\n
, significa:
-
%s
: consuma e imprima o próximo argumento não utilizado (ou seja, primeiro) emargs...
(ou seja, sua primeira linha). -
\n
: imprima uma nova linha. -
%s
: consuma e imprima o próximo argumento não utilizado (ou seja, segundo) emargs...
(ou seja, sua segunda linha). -
\n
: imprima uma nova linha.
Quando houver mais argumentos após a string de formato do que a string de formato exige, o comando printf
recomeça a partir do início da string de formatação. Assim, enquanto menos auto-documentando, você poderia escrever apenas '%s\n'
(em vez de '%s\n%s\n'
) para a string de formato, e produziria a mesma saída nesse caso.
Não tentarei documentar amplamente printf
aqui. Em vez disso, veja:
- A saída de
help printf
. - A
printf
da subseção de 4.2 Comandos Bash Builtin em o manual de referência da bash . - Esta página de manual, documentando o comando printf padrão (que bash se estende ligeiramente).
- A função
printf()
na biblioteca C padrão, na qual o comandoprintf
é baseado, e a qual é referida explicitamente nos recursos acima. A documentação, como esta página , é mais completa e mais acessível do que a maioria das fontes naprintf
comando. E a sintaxe da string de formato é muito semelhante.
Caminho 5: use cat
e um documento aqui.
Este caminho é especialmente valioso quando há muitas entradas e scripts. Se você estiver usando o shell de forma interativa ao invés de escrever um script, você pode usar isso, mas por favor considere Way 6 abaixo primeiro.
Enquanto echo
e printf
imprimem texto com base no conteúdo de seus argumentos de linha de comando, cat
imprime o conteúdo de seus arquivos de entrada (conforme especificado na linha de comando) ou, se não houver nenhum (ou passado -
), sua entrada padrão .
Sem redirecionamentos, a entrada padrão é o que você digita no terminal de controle de um programa. Aqui, os documentos são um tipo especial de redirecionamento. As linhas são coletadas até que uma palavra-chave especificada (eu usei EOF
) apareça sozinha em uma linha. Em seguida, as linhas até, mas não incluindo EOF
(ou o que você usou) são fornecidas como entrada padrão para o comando que está sendo executado.
cat >> note.txt << EOF
writes (>> appends) in note.txt this text
on 2 lines (with "-e" and "\n" help)
EOF
Uma das diferenças entre citar "
e '
é que a maioria das expansões e substituições com $
(por exemplo, $varname
) são executadas entre aspas duplas, mas nenhuma está entre aspas simples. Há também duas maneiras de usar aqui os documentos, com base em se $
(e também '
e \
) deve receber um significado especial ou ser tratado literalmente.
Nesse caso, não importa - $
e '
não aparecem, e \
só é tratado especialmente em um documento aqui quando ele escapa de um metacaracteres da casca (não n
). Assim como nas expressões com aspas simples e duplas, as duas formas tratam \n
literalmente. (Lembre-se, você precisou usar um recurso especial de echo
, ativado por -e
, para obter \n
tratado especialmente.)
Mas você sabe de outras aplicações:
- A maneira mostrada acima executará expansões e substituições, tratando
$
,'
e\
especialmente quando elas aparecem em um contexto em que seu significado especial se aplica. - Para fazer com que todo o texto seja tratado literalmente, cite a totalidade ou parte da palavra que aparece à direita de
<<
com'
,"
,\
ou uma combinação deles (por exemplo,cat >> note.txt << 'EOF'
).
Caminho 6: use cat
sem nenhum redirecionamento de entrada.
Se você estiver usando o shell interativamente, por padrão, a entrada padrão do shell é do seu terminal. Quando você executa um programa, por padrão, a entrada padrão do programa também é obtida do seu terminal. (Isso pode ser alterado por redirecionamentos de entrada, é claro).
Portanto, se você estiver executando um comando de forma interativa e desejar usar o cat
com >>
ou >
output redirection para enviar dados para um arquivo, não será necessário redirecionar nenhuma entrada. Basta digitar:
cat >> note.txt
writes (>> appends) in note.txt this text
on 2 lines (with "-e" and "\n" help)
^D
Em vez de ^D
, não insira um literal ^D
. Em vez disso, pressione Ctrl + D . Isso indica ao seu terminal que ele deve informar fim do arquivo (isto é, que quando o programa em execução pede mais informações, é informado que não existe nenhum, como se tivesse chegado ao fim de um arquivo normal armazenado no disco). Quando cat
vê que não há mais entrada, ela sai e você retorna ao shell.
Se você estiver escrevendo um script, o Way 6 não funcionará, porque o bash lê os comandos de um arquivo, mas a entrada padrão ainda é (normalmente) uma outra coisa, como seu terminal.
Uma diferença notável entre usar cat
com um documento here e usar cat sem redirecionamento de entrada, mesmo quando a entrada padrão é o seu terminal, é isso:
-
cat >> note.txt
escreve uma linha por vez paranote.txt
. Cada vez que você pressiona Enter , uma linha é gravada emnote.txt
. -
cat >> note.txt << EOF
leva toda a entrada até a linhaEOF
, então anexa anote.txt
. Se você interromper a entrada pressionando Ctrl + C , nada será escrito (e senote.txt
já não existir, nem sequer será criado).