Remova linhas em branco com grep

164

Eu tentei grep -v '^$'no Linux e isso não funcionou. Este arquivo veio de um sistema de arquivos do Windows.

nó ninja
fonte

Respostas:

300

Tente o seguinte:

grep -v -e '^$' foo.txt

A -eopção permite padrões de expressão regular para correspondência.

As aspas simples ^$fazem com que funcione para Cshell. Outras conchas ficarão felizes com aspas simples ou duplas.

UPDATE: Isso funciona para mim para um arquivo com linhas em branco ou "todos os espaços em branco" (como linhas de janelas com finais de linha de estilo "\ r \ n"), enquanto o acima remove apenas arquivos com linhas em branco e finais de linha de estilo unix:

grep -v -e '^[[:space:]]*$' foo.txt
ars
fonte
Esse egrep funcionaria apenas para arquivos com zero ou 1 espaço na linha, não para arquivos com 2 ou mais espaços. Mudança ? para *.
Ed Morton
4
Isso deve ser grep -E -v, tudo depois -eé interpretado como o padrão.
jazzpi
6
grep -v -e '^[[:space:]]*$' -e '^#' filefornecerá a você todas as linhas não em branco e sem comentários em um script ou arquivo de configuração (ou qualquer tipo de arquivo que use o caractere hash para comentários).
palswim
"A -eopção permite padrões regex para correspondência." Isso é muito enganador . -eé uma definição (POSIX-) para: This can be used to specify multiple search patterns, or to protect a pattern beginning with a hyphen (-).(do manual ). O Grep já espera uma expressão regular (básica) por padrão. Por este padrão, você pode deixar de fora -einteiramente: grep -v '^[[:space:]]*$' foo.txt.
Yeti
73

Mantenha simples.

grep . filename.txt
Frej Connolly
fonte
1
isso me dá todas as linhas no arquivo
phuclv
2
@ LưuVĩnhPhúc Deve emitir todas as linhas do arquivo, exceto as linhas em branco.
21417 Frej Connolly
2
Isso funciona para mim em arquivos de um sistema baseado em Linux, mas não em arquivos do Windows. Presumivelmente por causa dos caracteres de final de linha do Windows.
Estou votando nisso mesmo que isso não resolva completamente o problema do OP de lidar com um arquivo com finais de linha do Windows, mas como não tenho esse problema, essa acabou sendo a solução perfeita para mim.
David Z #
1
Esta é a solução perfeita. Simples e trabalhou no Linux.
W00f 21/02
30

Usar:

$ dos2unix file
$ grep -v "^$" file

Ou simplesmente awk:

awk 'NF' file

Se você não possui o dos2unix, poderá usar ferramentas como tr :

tr -d '\r' < "$file" > t ; mv t "$file"
ghostdog74
fonte
Não foi possível encontrar o programa dos2unix. Isso é para Windows? o comando ask também não funciona.
node ninja
perguntar? Não é isso awk.
Iconoclast
Um bom argumento sobre a conversão para terminações de linha no estilo UNIX, caso contrário, expressões regulares podem não funcionar conforme o esperado. Nada aqui funcionou para mim até eu converter as terminações de linha.
Ryan H.
16
grep -v "^[[:space:]]*$"

The -v makes it print lines that do not completely match

===Each part explained===
^             match start of line
[[:space:]]   match whitespace- spaces, tabs, carriage returns, etc.
*             previous match (whitespace) may exist from 0 to infinite times
$             match end of line

Executando o código

$ echo "
> hello
>       
> ok" |
> grep -v "^[[:space:]]*$"
hello
ok

Para entender mais sobre como / por que isso funciona, recomendo ler expressões regulares. http://www.regular-expressions.info/tutorial.html

Sepero
fonte
2
Como e por que isso funciona? Sua resposta seria muito melhor se você pudesse explicar. Por exemplo, sua expressão regular corresponde ao início da string e, em seguida, a um ou mais espaços usando o padrão POSIX e ao final da string, ou seja, com grep -v, remove todas as linhas que são apenas espaços. Certo? O que acontece se não houver espaços; é simplesmente um personagem de nova linha?
Ben
Como meu exemplo mostra, mesmo apenas uma linha vazia é removida (a primeira linha). Eu adicionei mais informações, então espero que ajude. :)
Sepero 8/12/12
3

Prefiro usar egrep, embora no meu teste com um arquivo genuíno com linha em branco sua abordagem tenha funcionado bem (embora sem aspas no meu teste). Isso funcionou também:

egrep -v "^(\r?\n)?$" filename.txt
chryss
fonte
Tentei isso. Linhas em branco ainda estão aparecendo. Isso pode acontecer porque o arquivo foi criado no Windows?
node ninja
3

Se você tiver seqüências de várias linhas em branco em uma linha e desejar apenas uma linha em branco por sequência, tente

grep -v "unwantedThing" foo.txt | cat -s

cat -s suprime repetidas linhas de saída vazias.

Sua saída iria de

match1



match2

para

match1

match2

As três linhas em branco na saída original seriam compactadas ou "comprimidas" em uma linha em branco.

Senol Erdogan
fonte
2
awk 'NF' file-with-blank-lines > file-with-no-blank-lines
Tim
fonte
2

O mesmo que as respostas anteriores:

grep -v -e '^$' foo.txt

Aqui, grep -esignifica a versão estendida do grep . '^ $' significa que não há nenhum caractere entre ^ (Início da linha) e $ (final da linha). '^' e '$' são caracteres de expressão regular.

Então o comando grep -v imprimirá todas as linhas que não correspondem a esse padrão (sem caracteres entre ^ e $).

Dessa forma, as linhas em branco vazias são eliminadas.

PaiMathew
fonte
-enão significa "a versão estendida do grep", talvez você esteja confuso -E? O manual diz claramente que -eapenas diz explicitamente que um padrão segue. Como o padrão não inicia com um traço, e você está definindo apenas um padrão de qualquer maneira, é possível deixá-lo de fora, pois por padrão o grep espera um padrão de regex: grep -v '^$' foo.txt(não há necessidade de funcionalidade de regex estendida). Também vale ressaltar que isso não elimina as linhas em branco no arquivo, apenas as que são canalizadas pela saída. Para esse caso, sed -iseria a ferramenta certa.
Yeti
1

Eu tentei muito, mas isso parece funcionar (supondo que \rvocê esteja te mordendo aqui):

printf "\r" | egrep -xv "[[:space:]]*"
mvds
fonte
Isso funciona se eu substituir a primeira parte pela saída do arquivo.
Node ninja
0

Usando Perl:

perl -ne 'print if /\S/'

\S significa combinar caracteres não em branco.

Majid Azimi
fonte
0

egrep -v "^ \ s \ s +"

O egrep já faz regex e o \ s é um espaço em branco.

O + duplica o padrão atual.

O ^ é para o começo

Jonni2016aa
fonte
0

Usar:

grep pattern filename.txt | uniq
baitisj
fonte
uniqreduzirá as linhas em branco adjacentes a apenas uma linha em branco, mas não as removerá completamente. Ainda assim, eu gosto de tentar usar uniqassim. A classificação primeiro removeria efetivamente todas as linhas em branco - deixando apenas uma, mas reorganizar a ordem das linhas pode não ser aceitável.
Zach Young
Bom ponto. Isso também chomp linhas repetidas. Acho que minha solução introduz bugs.
baitisj
0

Aqui está outra maneira de remover as linhas brancas e as linhas que começam com o #sinal. Eu acho que isso é bastante útil para ler arquivos de configuração.

[root@localhost ~]# cat /etc/sudoers | egrep -v '^(#|$)'
Defaults    requiretty
Defaults   !visiblepw
Defaults    always_set_home
Defaults    env_reset
Defaults    env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR
LS_COLORS"
root    ALL=(ALL)       ALL
%wheel  ALL=(ALL)       ALL
stack ALL=(ALL) NOPASSWD: ALL
lauc.exon.nod
fonte
0

É verdade que o uso de grep -v -e '^ $' pode funcionar, no entanto, não remove linhas em branco que possuem 1 ou mais espaços . Eu achei a resposta mais fácil e simples para remover linhas em branco é o uso do awk . O seguinte é um pouco modificado dos caras do awk acima:

awk 'NF' foo.txt

Mas como essa pergunta é para usar o grep, vou responder o seguinte:

grep -v '^ *$' foo.txt

Nota : o espaço em branco entre ^ e *.

Ou você pode usar \ s para representar o espaço em branco como este:

grep -v '^\s*$' foo.txt
MarcT
fonte