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 início e no final é o mesmo para cada arquivo.
Com base no código que obtive 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 eram para atuar em arquivos individuais. Pensei em tentar agir em vários arquivos usando o curinga, *.txt
.
Posso estar cometendo outros erros também. Em qualquer caso, como faço anexar texto ao início e ao final de vários arquivos?
Resposta
Para anexar texto a um arquivo que você pode usar (com o Implementação GNU de 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
Resposta
Você pode usar GNU sed
Como já ilustrado, você pode inserir linhas de texto antes e depois da correspondência linhas de um arquivo com sed
, usando os comandos i
e a
respectivamente. “foi mostrado que você pode fazer isso com uma linha e por vários arquivos de uma vez.
O seguinte irá inserir uma linha antes do primeiro 1i
e 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 i
e a
não funcionam apenas com números de linha, mas também em cada linha que corresponde 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
Resposta
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 printf
parte do comando por si só, verá os comandos de edição exatos que está passando para ex
:
0a var language = { . $a }; . x
0a
significa “Anexar texto após a linha 0 “(em outras palavras, antes da primeira linha). A próxima linha é o texto literal a “anexar” após a linha 0. O ponto (.
) em uma linha por si só termina o texto a ser anexado.
$a
significa acrescentar texto após a última linha do arquivo.
x
significa salvar as alterações e sair .
Resposta
Esta é uma maneira de fazer isso em Perl:
for f in ./*txt; do perl -lpe "BEGIN{print "First string"}END{print "Last string"}" "$f" > foo && mv foo "$f"; done
Comentários
Resposta
Também tem o direito de ser (com resultados em .out
arquivos):
find . -name "*.txt" -exec sh -c "(echo HEAD;cat {};echo FOOT) > {}.out" \;
Outra variante mais elaborada – arquivos de origem substituídos por resultado:
find . -name "*.txt" -exec sh -c "(echo HEAD;cat {};echo FOOT) > {}.tmp && mv {}.tmp {}" \; -print
Resposta
Tente usar ex
:
ex -s +"bufdo!1s/^/HEAD/|$s/$/TAIL/" -cxa *.foo
onde os comandos são:
-
bufdo!
executa os comandos abaixo para cada buffer / arquivo aberto (observação: não é POSIX ) -
1s/^/HEAD/
– insereHEAD
texto na primeira linha no início da linha -
$s/$/TAIL/
– acrescentaTAIL
texto na última linha no final da linha
e os argumentos são:
-
-s
– modo silencioso / rápido -
-cxa
– salvar todos os buffers / arquivos abertos e sair -
*.foo
– todos os arquivos no diretório atual (*
) comfoo
extensão, use**/*.foo
para recursividade (depois de habilitar o globstar:shopt -s globstar
)
Comentários
- note que bufdo não é POSIX pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html
- @StevenPenny está certo. Eu uso somente recursos especificados do POSIX, pessoalmente, para edições com script.
Resposta
Com gnu awk
, usando o inplace
extensão e BEGINFILE
/ ENDFILE
:
gawk -i inplace "BEGINFILE{print "INSERT"};ENDFILE{print "APPEND"};1" ./*.txt
Resposta
Uma linha em Perl para o resgate:
perl -i -pe"$_="FIRST LINE\n$_"if$.<2;$.=0,$_.="LAST LINE\n"if eof" *.txt
-i
em vez dessa substituição de arquivo não funciona, ela apenas imprime em stdout.