Existe um comando Unix para acrescentar alguns dados de string a um arquivo de texto?
Algo como:
prepend "to be prepended" text.txt
unix
command-line
utilities
prepend
Um dois três
fonte
fonte
<<(echo "to be prepended") < text.txt | sponge text.txt
Respostas:
-i
grava a alteração no local e faz um backup se alguma extensão for fornecida. (Nesse caso,.old
)1s;^;to be prepended;
substitui o início da primeira linha pela sequência de substituição fornecida, usando;
como um delimitador de comando.fonte
\n
depois de pré-anexado; dependendo de suas necessidades. Solução pura.inFile
incluir diretórios em seu caminho?\n
. Deveria ter lido os comentários primeiro. Droga.'1s;^;my-prepended-line\;\n;'
fonte
git config --get-regex $arg | sed -r 's/\t{3}/\\n/g';
e isso atrapalha quando converte o\t
e\n
.echo "to be prepended"$'\n'"$(cat text.txt)"
Substituição de Processo
Estou surpreso que ninguém tenha mencionado isso.
o que é indiscutivelmente mais natural do que a resposta aceita (imprimir algo e encaminhá-lo para um comando de substituição é lexicograficamente contra-intuitivo).
... e seqüestrar o que ryan disse acima, com
sponge
você não precisa de um arquivo temporário:EDIT: Parece que isso não funciona no Bourne Shell
/bin/sh
Aqui String (apenas zsh)
Usando uma string here -
<<<
, você pode:fonte
<<(echo "to be prepended") < text.txt
e<<< "to be prepended" < text.txt
não funcionam no bash; eles exigem zsh.Esta é uma possibilidade:
você provavelmente não conseguirá facilmente contornar um arquivo intermediário.
Alternativas (pode ser complicado com o escape da concha):
fonte
cat <(echo "to be prepended") text.txt > newfile.txt
. Venha para pensar sobre isso, não tenho certeza se o meu está relacionado, por isso estou postando uma resposta separada.Isso funcionará para formar a saída. O - significa entrada padrão, que é fornecida através do tubo a partir de eco.
Para reescrever o arquivo, é necessário um arquivo temporário, pois não é possível canalizar novamente para o arquivo de entrada.
fonte
text.txt
conforme solicitado, mas o exibe no stdout. A saída poderia ser canalizados para um arquivo diferente se isso funciona para o OPPrefira a resposta de Adam
Podemos facilitar o uso da esponja . Agora não precisamos criar um arquivo temporário e renomeá-lo por
fonte
Se for aceitável substituir o arquivo de entrada:
Nota:
Isso pode ter efeitos colaterais inesperados, principalmente o potencial de substituir um link simbólico por um arquivo normal, terminar com permissões diferentes no arquivo e alterar a data de criação (nascimento) do arquivo.
sed -i
, como na resposta do príncipe John Wesley , tenta pelo menos restaurar as permissões originais, mas as outras limitações também se aplicam.Aqui está uma alternativa simples que usa um arquivo temporário (evita a leitura de todo o arquivo de entrada na memória da maneira que a solução do shime faz):
Usar um comando de grupo (
{ ...; ...; }
) é um pouco mais eficiente do que usar um subshell ((...; ...)
), como na solução de 0xC0000022L .As vantagens são:
É fácil controlar se o novo texto deve ser anexado diretamente à primeira linha ou se deve ser inserido como nova (s) linha (s) (basta anexar
\n
aoprintf
argumento).Diferentemente da
sed
solução, ele funciona se o arquivo de entrada estiver vazio (0
bytes).A
sed
solução pode ser simplificada se a intenção for anexar uma ou mais linhas inteiras ao conteúdo existente (assumindo que o arquivo de entrada não esteja vazio):sed
Ai
função de insere linhas inteiras:Com o GNU
sed
:Uma variante portátil que também funciona com o macOS / BSD
sed
:Observe que a nova linha literal após o
\
é necessária.Se o arquivo de entrada precisar ser editado no local (preservando seu inode com todos os seus atributos):
Usando o venerável
ed
utilitário POSIX :Nota:
ed
invariavelmente lê primeiro o arquivo de entrada como um todo na memória.Para anexar diretamente à primeira linha (como em
sed
, isso não funcionará se o arquivo de entrada estiver completamente vazio (0
bytes)):-s
ed
mensagens de status suprimidas .ed
como um documento aqui com várias linhas (<<EOF\n...\nEOF
), ou seja, via stdin ; por padrão, a expansão de strings é executada nesses documentos (variáveis de shell são interpoladas); cite o delimitador de abertura para suprimir isso (por exemplo,<<'EOF'
).1
torna a primeira linha a linha atuals
executa uma substituição de seqüência de caracteres baseada em regex na linha atual, como emsed
; você pode incluir novas linhas literais no texto de substituição, mas elas devem ser\
escapadas.w
grava o resultado de volta no arquivo de entrada (para teste, substituaw
por,p
para imprimir apenas o resultado, sem modificar o arquivo de entrada).Para acrescentar uma ou mais linhas inteiras :
Assim como
sed
ai
função, invariavelmente, adiciona uma nova linha final ao texto a ser inserido.0 i
torna0
(o início do arquivo) a linha atual e inicia o modo de inserção (i
); observe que os números de linha são1
baseados em outras coisas ..
em sua própria linha.fonte
Provavelmente nada embutido, mas você poderia escrever o seu com bastante facilidade, assim:
Algo assim pelo menos ...
fonte
$$
é insuficiente para o código de produção (ataque do symlink do google); mas certamente é melhor que um nome de arquivo estático.mktemp
Em algumas circunstâncias, o texto anexado pode estar disponível apenas no stdin. Então essa combinação deve funcionar.
Se você deseja omitir a
tee
saída, acrescente> /dev/null
.fonte
tee
não atrapalhatext.txt
antes decat
conseguir lê-lo? Acho que não - o que tornaria essa solução perigosa para a saúde do arquivo.lenA=1000000; yes a | head -c $lenA > a.txt; lenB=10000; b=$(yes b | head -c $lenB); echo "$b" | cat - a.txt | tee a.txt > /dev/null
. SelenA
for 1000000 (arquivo de 1 Mb) elenB
10000 (prefixo de 10 KB de texto), o arquivo "a.txt" será substituído por 20 KB de letras "b". Isso está totalmente quebrado. Agora, se você usar 1Mb a.txt e 1Mb de texto paratee
acrescentar , entra em um loop que gera um arquivo de 7Gb +, tive que interromper o comando. Portanto, é óbvio que o resultado é imprevisível para tamanhos grandes. Não tenho informações se deve funcionar em tamanhos pequenos.Solução:
Observe que isso é seguro em todos os tipos de entradas, porque não há expansões. Por exemplo, se você deseja anexar
!@#$%^&*()ugly text\n\t\n
, funcionará apenas:A última parte que resta para consideração é a remoção de espaço em branco no final do arquivo durante a substituição de comandos
"$(cat file.txt)"
. Todas as soluções para isso são relativamente complexas. Se você deseja preservar as novas linhas no final do arquivo.txt, consulte: https://stackoverflow.com/a/22607352/1091436fonte
file.txt
for maior do que o que pode ser ajustado na lista de argumentosprintf
.Outra maneira de usar
sed
:Se a linha a ser anexada for multilinha:
fonte
sed -i '1ito be prepended' inFile
- ou é permitido apenas para o GNU sed?sed
, oi
comando é seguido por uma barra invertida e uma nova linha, e cada linha de entrada, exceto a última, também termina com uma barra invertida. O GNUsed
permite atalhos nas linhas que você pergunta, mas é apenas o GNUsed
que o faz. 'Conforme testado no Bash (no Ubuntu), se iniciar com um arquivo de teste via;
echo "Original Line" > test_file.txt
você pode executar;
echo "$(echo "New Line"; cat test_file.txt)" > test_file.txt
ou, se a versão do bash for muito antiga para $ (), você poderá usar backticks;
echo "`echo "New Line"; cat test_file.txt`" > test_file.txt
e receba o seguinte conteúdo de "test_file.txt";
Nenhum arquivo intermediário, apenas bash / eco.
fonte
Outra solução bastante direta é:
fonte
cat
expansão de parâmetro entre aspas duplas é uma boa razão para um voto negativo . Esse código está dividindo o conteúdo do arquivo em palavras e passando cada uma dessas palavras como um argumento separado paraecho
. Você perde os limites do argumento original, perde novas linhas / guias / etc., E cadeias de caracteres como\t
e\n
no texto original são substituídas por guias e novas linhas em vez de serem mantidas como estavam.Se você gosta do vi / vim, este pode ser o seu estilo.
fonte
fonte
Eu recomendo definir uma função e, em seguida, importar e usá-la quando necessário.
Em seguida, use-o assim:
O conteúdo do seu arquivo será:
Estou prestes a usar essa abordagem para implementar um atualizador de log de alterações.
fonte