Como inserir texto antes da primeira linha de um arquivo?

76

Eu estive olhando ao redor do sedcomando para adicionar texto em um arquivo em uma linha específica. Isso funciona adicionando texto após a linha 1:

sed '1 a\

Mas quero adicioná-lo antes da linha 1. Seria:

sed '0 a\

mas eu recebo este erro: invalid usage of line address 0.

Alguma sugestão?

Manolo
fonte
stackoverflow.com/questions/15157659/…
Léo Léopold Hertz 준영

Respostas:

101

Use seda iopção insert ( ) que irá inserir o texto na linha anterior.

sed '1 i\

Pergunta author's update:

Para fazê-lo editar o arquivo no lugar - com o GNU sed- eu tive que adicionar a -iopção:

sed -i '1 i\anything' file

Também sintaxe

sed  -i '1i text' filename

Para sed não GNU

Você precisa pressionar a tecla Enter imediatamente após a barra invertida 1i\e depois first_line_text:

sed -i '1i\
first_line_text
'

Observe também que algumas sedimplementações não-GNU (por exemplo, a do macOS) exigem um argumento para o -isinalizador (use -i ''para obter o mesmo efeito que o GNU sed).

suspeito
fonte
1
Não funciona sem -iopção. Atualizarei sua resposta antes de aceitar.
Manolo
1
obrigado. Qual sistema operacional você está usando? Solução original trabalhou em OpenSuse 9.
suspectus
1
Interessante! Estou no Lubuntu 13.10 e sed '1 i\this text is entered above the existing first line' filefunciona para mim.
2
Aqui, usando sed (GNU sed) 4.2.2apenas sed '1 i text to insert' -i filefuncionou como um encanto. Obrigado
ton
1
@FeRD Veja minha awkresposta incorreta abaixo. Isso deve funcionar.
Rudimeier 04/0318
18

Eco é usado para obter o texto. Nome do arquivo Cat - imprime o arquivo no console e o usa para enviar para outro arquivo filename1 e, em seguida, movemos o nome do arquivo1 para o nome do arquivo para inserir o texto na primeira linha do arquivo desejado.

  (echo "some text" && cat filename) > filename1 && mv filename1 filename
Ankit Shah
fonte
7
Por favor, deixe-me saber por que o seguinte é downvoted
Ankit Shah
1
Talvez porque o OP mencione sed. Isso não merece um voto negativo na minha opinião. Essa solução foi a que melhor atendia às minhas necessidades, depois votada.
рüффп
Eu votei. funciona no ksh para mim.
arcee123 22/08
16

Você pode usar o Vim no modo Ex:

ex -sc '1i|ALFA BRAVO' -cx file
  1. 1 selecione a primeira linha

  2. i inserir texto e nova linha

  3. x salvar e fechar

Steven Penny
fonte
7

Você deseja inserir texto antes da primeira linha, em vez de anexá- lo depois; portanto, use

sed '1 i\
your_text' your_file

Um documento aqui também pode ajudar:

cat /dev/stdin your_file <<EOI
Your text
goes here
EOI
Joseph R.
fonte
6

Usando o GNU awk> = 4.1:

awk -i inplace 'BEGINFILE{print "first line"}{print}' foo.sh

Ao contrário de todas as sedrespostas, isso também funciona em arquivos vazios.

rudimeier
fonte
inplaceé uma biblioteca e, infelizmente, aparece em todas as distribuições awk. Eu recebo "awk: fatal: não é possível abrir arquivo de origem 'inplace' para leitura"GNU Awk 4.2.1, API: 2.0 (GNU MPFR 4.0.1, GNU MP 6.1.2)
vossad01
6
sed  -i '1i new_text' file_name

Se você não especificar a -iopção, ela não mostrará nenhum erro e exibirá a saída no terminal padrão, mas não inserirá o texto no arquivo.

devi.
fonte
A questão não é sobre a -itroca.
31516 don_crissti
Como você acha isso? Ele é uma resposta para a pergunta. Sim, é semelhante à resposta aceita, mas não exatamente a mesma.
G-Man
@ G-Man - pode-se argumentar o modelo usado por cas está longe de ser ideal, mas realmente, este é semelhante como em quase idêntico ... a diferença sendo o espaçamento eo fato de este não tem nenhum barra invertida. No que me diz respeito, eles são tecnicamente idênticos (pois são gnu sedespecíficos e, por acaso, gnu sedeles aceitarão a ibarra invertida). Se outros acham que isso merece uma resposta separada + um voto positivo ... tudo bem.
31416 Don_crissti
2

O 0acomando que tentou se trabalhar em ex, o antecessorvi :

printf '%s\n' 0a 'Anything you want to add' . x | ex file.txt

O printfcomando por si só gera:

0a
Anything you want to add
.
x

Os 0ameios são acrescentados após a 0ª linha (ou seja, antes da primeira linha).

A próxima linha ou várias linhas é um texto literal a ser adicionado.

O .em uma linha por si só termina o comando "acrescentar".

As xcausas Ex para salvar as alterações para o arquivo e saia.

Curinga
fonte
1

Estou surpreso que nesta pergunta antiga ninguém tenha mostrado o comando sed mais comum (e bastante simples nesse caso):

$ sed  -i '1s/^/new_text\
/' file_name

Que funciona na maioria das conchas e é portátil para várias versões sed.
Se o GNU sed estiver disponível, você poderá usar o seguinte:

$ sed -i '1s/^/new_text\n' file_name

A diferença é que o GNU sed permite o uso de a \npara uma nova linha e outros precisam de uma nova linha literal precedida por uma barra invertida (que também funciona no GNU sed de qualquer maneira).

Se um shell que aceita a $'…'sintaxe estiver em uso, você poderá inserir a nova linha diretamente, para que o sed veja que a nova linha já está lá:

$ sed -i $'1s/^/new_text\\\n/' file_name

O que funciona para versões mais sed.

Isaac
fonte
-1

Infelizmente, todas as respostas acima (principalmente com sed) não funcionaram para mim, pois todas substituíram a primeira linha. Eu estou em uma Ubuntu 16.04 LTSmáquina. Aqui está minha solução alternativa com GNU Awk 4.0.2:

awk '{if(NR==1){$0="NEW_FIRST_LINE"$0; print $0} ;if(NR!=1){print $0}}' file_name
Splinter479
fonte
1
Não tenho certeza do que você está falando ... Há apenas uma sedresposta que usa substituição, mas não substitui a linha existente.
22818 Don -crissti
-1

Primeiro e último

Eu diria que qualquer um que tenha pesquisado como inserir / anexar texto ao início / fim de um arquivo provavelmente também precisará saber como fazer o outro.

cal |                            \
  gsed -E                        \
       -e     '1i\{'             \
       -e     '1i\  "lines": ['  \
       -e 's/(.*)/    "\1",/'    \
       -e '$s/,$//'              \
       -e     '$a\  ]'           \
       -e     '$a\}'

Explicação

Isso é calenviado para o gnu- sed(chamado gsedno macOS instalado via brew.sh ) com RegEx ( -E) estendido e 6 "scripts" aplicados ( -e) e as quebras de linha são escapadas \para facilitar a leitura. Os scripts 1 e 2 usam 1i\"na linha 1, insira". Os scripts 5 e 6 costumam $a\"na linha <último>, acrescentar". Alinhei verticalmente as saídas de texto para fazer o código representar o que é esperado no resultado. Os scripts 3 e 4 fazem substituições (o último se aplica somente à "linha <última>"). O resultado é a conversão da saída do comando para JSON válido.

resultado

{
  "lines": [
    "    October 2019      ",
    "Su Mo Tu We Th Fr Sa  ",
    "       1  2  3  4  5  ",
    " 6  7  8  9 10 11 12  ",
    "13 14 15 16 17 18 19  ",
    "20 21 22 23 24 25 26  ",
    "27 28 29 30 31        ",
    "                      "
  ]
}
Bruno Bronosky
fonte
Embora eu não tenha votado em sua pergunta, observe que já temos várias respostas, incluindo uma aceita, que demonstram o resultado desejado.
Jeff Schaller
@JeffSchaller A comunidade Stack Exchange não é um fórum. Seu objetivo vai além de ajudar o OP a ser desbloqueado. O objetivo é propagar a base de conhecimento global com muitas opções que os candidatos podem encontrar ao procurar respostas. O motivo pelo qual intitulei minha resposta é ajudar os usuários a reconhecerem a utilidade dessa resposta antes mesmo de clicarem no resultado do Google.
Bruno Bronosky 22/10
O que estou dizendo é que sua resposta não está fornecendo novas opções (respostas) para futuros leitores desta pergunta. Já temos quatro respostas que usam variações de 1ipara inserir texto antes da primeira linha. Alguém com essa pergunta precisaria extrair as partes necessárias da sua resposta para resolver o problema. As perguntas são gratuitas, por isso, convido você a fazer e responder sua própria pergunta para fornecer sua resposta específica.
Jeff Schaller