Substituindo várias linhas em branco por uma única linha em branco no vim / sed

42

Pergunta mais ou menos diz tudo. Estou ciente de que /^$/dremoverá todas as linhas em branco, mas não consigo ver como dizer 'substituir duas ou mais linhas em branco por uma única linha em branco'

Alguma ideia?

Andrew Bolster
fonte

Respostas:

48

Se você não estiver disparando o vim ou sed para outro uso, o gato realmente tem uma maneira fácil de recolher várias linhas em branco, basta usar cat -s.

Se você já estava no vim e queria ficar lá, você pode fazer isso com a pesquisa interna e substituí-lo, emitindo: :%s!\n\n\n\+!^M^M!g(O ^ M é a representação visual de uma nova linha, você pode inseri-la pressionando Ctrl+ vEnter) ou salve a opção digitando por apenas descascar para fora para gato: :%!cat -s.

Caleb
fonte
uau, não sabia a -sopção do gato - apenas uma nota histórica, não está no POSIX, mas parece estar disponível no BSD e no GNU cat.
Maxschlepzig
2
Marcando como 'vencedor' para o :%!cat -s. Aprenda algo GNnew todos os dias!
Andrew Bolster
3
Eu acho que você também pode usar \ r em vez de ^ M assim:%s!\n\n\n\+!\r\r!g
Niko Bellic
Eu precisava disso hoje. Obrigado Caleb! :)
Dɑvïd 11/06
19

Use \npara indicar uma nova linha no padrão de pesquisa. Use Ctrl+ Mno texto de substituição ou em uma referência anterior. Veja :help patterne :help sub-replace-special(linkado de :help :s).

%s/\(\n\n\)\n\+/\1/
Gilles 'SO- parar de ser mau'
fonte
Você pode explicar como é que o padrão de pesquisa?
Sagar Jain
@sjmp Requisito: substitua duas ou mais linhas em branco por uma única linha em branco. Implementação: substitua três ou mais novas linhas consecutivas por apenas duas novas. Consulte o manual para obter uma explicação das construções usadas no comando.
Gilles 'SO- stop be evil'
Mas por que você precisa usar um grupo quando seu conteúdo é corrigido?
23617 Sabuncu
@Sabuncu Você não precisa usar um grupo. Mas por que não usar um grupo? Aqui, usei um grupo porque você não pode copiar e colar um comando com uma nova linha no texto de substituição: você precisa inserir um caractere Ctrl + M literal, \nnão funciona no texto de substituição.
Gilles 'SO- stop be evil'
Agora entendo, obrigado por dedicar um tempo para responder.
Sabuncu
6

Se no Vim, faça o seguinte:

:%!cat -s
coanor
fonte
2
Você pode adicionar um pequeno detalhe sobre como isso funciona, mesmo que seja apenas uma citação da manpágina.
precisa saber é o seguinte
Não funcionou no windows 7
user674669
0

Usando Perl:

perl -00 -pe ''

-00 A opção de linha de comando ativa o modo slurp de parágrafo, o que significa que Perl lê texto parágrafo por parágrafo, em vez de linha por linha.

Majid Azimi
fonte
0

Com sed (GNU sed) 4.2.2:

sed -r '
  /^\s*$/ { 
    # blank line
:NEXT
    N # append next line to pattern space - if none, autoprint PS and exit
    s/^\s*$\n^\s*$//g;t NEXT # if 2 blank lines, clear PS and loop to NEXT
  }
  # else, autoprint PS and next/exit
' < $MYFILE
PJ_Finnegan
fonte
-2

Eu sei que esse é um código bobo, mas eu queria resolver esse problema em menos de 10 minutos e funcionou

for file in /directory/*
do
  originalname=$file
  us='_'
  tempname=$file$us
  echo $originalname
  mv $originalname $tempname
  uniq $tempname $originalname
  rm $tempname
done
Mahmoud Zalt
fonte
1
uniqremove as linhas iguais adjacentes. O que não é o que o OP quer.
Pacholik
@pacholik ele disse claramente "Substituindo várias linhas em branco por uma única linha em branco" NÃO remova as linhas iguais adjacentes !!!
Mahmoud Zalt
3
Sim, exatamente ...
pacholik 31/03