Como anexar texto ao início e ao fim de vários arquivos de texto no Bash?

24

Eu tenho um diretório cheio de arquivos de texto. Meu objetivo é anexar texto ao início e ao final de todos eles. O texto que vai no começo e no final é o mesmo para cada arquivo.

Com base no código que recebi da Web, este é o código para anexar ao início do arquivo:

echo -e 'var language = {\n$(cat $BASEDIR/Translations/Javascript/*.txt)' > $BASEDIR/Translations/Javascript/*.txt

Este é o código para anexar ao final do arquivo. O objetivo é adicionar o texto };no final de cada arquivo:

echo "};" >> $BASEDIR/Translations/Javascript/*.txt

Os exemplos que tirei foram para atuar em arquivos individuais. Eu pensei em tentar atuar em vários arquivos usando o curinga *.txt,.

Eu posso estar cometendo outros erros também. De qualquer forma, como anexo texto ao início e ao fim de vários arquivos?

Questionador
fonte

Respostas:

27

Para acrescentar texto a um arquivo que você pode usar (com a implementação do GNU sed):

sed -i '1i some string' file

Anexar texto é tão simples quanto

echo 'Some other string' >> file

A última coisa a fazer é colocar isso em um loop que itera sobre todos os arquivos que você pretende editar:

for file in *.txt; do
  sed -i '1i Some string' "$file" &&
  echo 'Some other string' >> "$file"
done
Marco
fonte
8

Você pode usar o GNU sed

Como já ilustrado, você pode inserir linhas de texto antes e depois das linhas correspondentes de um arquivo sed, usando o comando ie, arespectivamente. O que não foi mostrado é que você pode fazer isso com uma linha e para vários arquivos ao mesmo tempo.

A seguir, será inserida uma linha antes da primeira 1ie após a última linha $a. As inserções serão executadas para todos os arquivos correspondentes ao glob *.txt.

sed -i -e '1ivar language = {' -e '$a};' -- *.txt

Ambos ie anão funcionam apenas com números de linha, mas também em todas as linhas que correspondem a um determinado padrão. Isso inseriria um comentário sempre que uma linha contivesse var y = 2;:

sed -i -- '/var y = 2;/i//initialize variable y' *.js
J. Katzwinkel
fonte
5

Comando totalmente compatível com POSIX, usando ex:

for f in *.txt; do printf '%s\n' 0a 'var language = {' . '$a' '};' . x | ex "$f"; done

Se você executar a printfparte do comando por si só, verá os comandos de edição exatos aos quais está passando ex:

0a
var language = {
.
$a
};
.
x

0asignifica "Anexar texto após a linha 0" (em outras palavras, antes da primeira linha). A próxima linha é o texto literal a ser "acrescentado" após a linha 0. O ponto ( .) em uma linha por si só termina o texto a ser acrescentado.

$a significa acrescentar texto após a última linha do arquivo.

x significa salvar as alterações e sair.

Curinga
fonte
2

Aqui está uma maneira de fazer isso no Perl:

for f in ./*txt; do
  perl -lpe 'BEGIN{print "First string"}END{print "Last string"}' "$f" > foo && 
  mv foo "$f";
done
terdon
fonte
A adição de StéphaneChazelas ao -iinvés dessa substituição de arquivo não funciona, apenas imprime no stdout.
Oleh Prypin
@OlehPrypin, de fato, você está certo. Comentário deletado.
Stéphane Chazelas
1

Tente usar ex:

ex -s +'bufdo!1s/^/HEAD/|$s/$/TAIL/' -cxa *.foo

onde os comandos são:

  • bufdo!executa comandos abaixo para cada arquivo / buffer aberto (nota: não é POSIX )
  • 1s/^/HEAD/- insere HEADtexto na primeira linha no início da linha
  • $s/$/TAIL/- acrescenta TAILtexto na última linha no final da linha

e argumentos são:

  • -s - modo silencioso / rápido
  • -cxa - salve todos os buffers / arquivos abertos e saia
  • *.foo- todos os arquivos no diretório atual ( *), com fooextensão, uso **/*.foode recursividade (após permitindo globstar: shopt -s globstar)
kenorb
fonte
1
nota bufdo não é POSIX pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html
Steven Penny
1
@StevenPenny está certo. Uso somente os recursos especificados no POSIX, pessoalmente, para edições com script.
Curinga
1

Com gnu awk, usando a inplaceextensão e BEGINFILE/ ENDFILE:

gawk -i inplace 'BEGINFILE{print "INSERT"};ENDFILE{print "APPEND"};1' ./*.txt
don_crissti
fonte
1

Também tem o direito de estar (com resultados em .outarquivos):

find . -name '*.txt' -exec sh -c '(echo HEAD;cat {};echo FOOT) > {}.out' \;

Outra variante, mais elaborada - arquivos de origem substituídos pelo resultado:

find . -name '*.txt' -exec sh -c '(echo HEAD;cat {};echo FOOT) > {}.tmp && mv {}.tmp {}' \; -print
torre
fonte
0

One-liner Perl para o resgate:

perl -i -pe'$_="FIRST LINE\n$_"if$.<2;$.=0,$_.="LAST LINE\n"if eof' *.txt
Kjetil S.
fonte