br comando para substituir uma linha em branco por duas linhas de conteúdo

3

Como substituo a primeira linha em branco por duas linhas de conteúdo? Eu vi uma pergunta em substituindo várias linhas em branco por uma única linha em branco no vim sed , mas não vejo como adaptar isso. Então, por exemplo, se meu arquivo de entrada for:

% abd
% def

% jkl

% mno

Eu gostaria de ter um comando sed que substitua apenas a linha em branco primeiro por essas duas linhas (uma contendo ghi e a outra contendo % ):

% abd
% def
% ghi
%
% jkl

% mno
    
por Peter Grill 24.05.2011 / 07:38

4 respostas

3

Sed corresponde a linhas inteiras, mas não inclui a nova linha, portanto, uma linha em branco será apenas uma string vazia. Você pode usar ^ para corresponder ao início de uma linha e $ para corresponder ao final, então ^$ corresponde a uma linha em branco. Apenas substitua por % ghi\n% :

sed 's/^$/% ghi\n%/'

A nova linha que já existia permanecerá, então você vai acabar com % ghi em uma linha e % na próxima

Editar : se precisar corresponder apenas uma vez, a expressão será um pouco mais complicada. A maneira mais fácil de fazer isso em sed é:

sed '0,/^$/ s/^$/% ghi\n%/'

A substituição é agrupada em um intervalo de endereços 0,/^$/ , o que significa "aplicar somente o seguinte às linhas entre 0 e a primeira linha que corresponde a ^$ ". Como a expressão de substituição também verifica ^$ , a única linha que realmente vai mudar é a primeira que corresponde a ^$ - a primeira linha em branco

    
por 24.05.2011 / 07:44
3

Aqui está outra forma com sed que substitui apenas a primeira linha vazia sem usar \n na extensão RHS ou gnu sed 0 :

sed '/^$/{      # if line is empty
x               # exchange pattern space w. hold space
//{             # if pattern space is empty (means the hold buffer was empty)
s//%/           # replace it with a % character
h               # overwrite hold space (so now hold space looks like this: ^%$)
s/$/ ghi/       # add a space and the string ghi after the %, then
G               # append content of hold buffer to pattern space so now the
}               # pattern space looks like this: ^% ghi\n%$
//!x            # if pattern space is not empty it means a change was
}               # already made so exchange back (do nothing)
' infile

um forro:

sed -e'/^$/{x;//{s//%/;h;s/$/ ghi/;G' -e'}' -e'//!x' -e'}' infile

Embora realmente, isso é um pouco fácil para ed :

ed -s infile <<< $'/^$/s//% ghi\\n%/\n,p\nq'

substitua ,p por w para editar o arquivo no local.

    
por 30.10.2015 / 22:27
2

NB: Isso responde à pergunta original, que pediu:

How do I replace a single blank line with two lines of content?

Isso não responde à pergunta "camaleão".

sed '/^$/{i\
% ghi\
%
d
}'

Quando sed encontra uma linha em branco, isso insere as duas linhas ' % ghi ' e ' % ' e, em seguida, exclui a linha em branco.

Dos comentários

This produces a syntax error.

Use uma concha real em vez de uma concha do mar; Isso salvará a dor de todos a longo prazo. Coloque os comandos em 5 linhas de um arquivo simples e use sed -f sed.script . Provavelmente existem outras maneiras de conseguir isso no shell C - isso funciona:

echo '/^$/{\'  > sed.script
echo '% ghi\' >> sed.script
echo '%'      >> sed.script
echo 'd'      >> sed.script
echo '}'      >> sed.script
sed -f sed.script data.file
rm -f sed.script
    
por 24.05.2011 / 07:50
1
sed -e1\!b -e:n -e"/^$/c$(printf '\\n%%%s' \ ghi '')" -en\;bn

sed entende três primitivos para gravações de cadeias fixas com scripts para stdout. Todos os três iniciam após a nova linha imediatamente seguinte, com escape da barra invertida no script, e terminam na primeira linha que não ocorreu no script ou no primeiro fim de arquivo que está ocorrendo no script:

  • i

    • i insere a cadeia fixa para o padrão agora
  • a

    • agenda a cadeia fixa para um a ppend para stdout na ordem da ocorrência do script antes do próximo ciclo de linha ou, para a última linha, no final deste,
  • c

    • exclui o espaço de padrão de todo o endereço [es] (1(,2)?)? , finaliza o ciclo de linha atual e c exibe a saída para a cadeia fixa para o último de qualquer endereço [ es]
printf '\n\n\n\n\n' |
sed -e1\!b -e:n \
    -e"/^$/c$(printf '\\n%%%s' \ ghi '')" \
    -en\;bn
% ghi
%




Portanto, este script b é extraído do script para cada linha que é ! , não a 1 st, mas da primeira linha até que possa c alterar uma linha em branco para a sequência fixa ele imprime automaticamente todas as linhas não em branco antes de sobrescrevê-las com n ext e retornar ao rótulo :n ext para ir novamente.

    
por 29.10.2015 / 21:32

Tags