Eu tenho um monte de arquivos de texto, alguns dos quais contêm linhas que estão vazias, ou seja, consistem apenas em uma nova linha, ou possíveis espaços seguidos por uma nova linha. Eu localizo os arquivos usando um find
comando.
- Arquivo de exemplo
#Title 1 12345678 1234 #Title 2 12345678 1234 12345678 1234
- Saída esperada
#Title 1 12345678 1234 #Title 2 12345678 1234 12345678 1234
Eu quero remover todas essas linhas vazias. Eu tentei com o seguinte comando no Debian Linux Stretch:
cat "/path/to/file" | sed '/^\s*$/d' | sponge "/path/to/file";
Alguns dos arquivos tinham, por exemplo, 4 ou mais linhas em branco à direita, mas o comando acima removeu apenas todas as linhas em branco, exceto uma.
Como eu poderia remover esta última linha em branco à direita? Como mencionado: se houver linhas em branco no arquivo, elas também devem ser removidas.
Estou tentando obter alguma consistência entre os arquivos, pois os arquivos são armazenados em uma matriz de tipos dentro de uma variável BASH. Os arquivos são então repetidos e todas as linhas em branco e linhas em branco à direita são removidas, enquanto alguns dos arquivos já não têm linhas em branco ou qualquer linha em branco à direita.
Se entendi sua pergunta corretamente, você deseja remover (verdadeiramente ou visualmente) linhas vazias de um arquivo de texto. Isso pode ser feito facilmente usando
awk
.Para um único arquivo, você pode chamar
Isso só imprimirá arquivos que tenham pelo menos um caractere "não em branco" na linha. A idéia por trás disso é que
awk
, por padrão, divide as linhas de entrada em "campos" em "espaço em branco", ou seja, execuções contíguas de caracteres de espaço e tabulação. No entanto, se uma linha for composta apenas por esses caracteres, o número de campos, armazenados internamente na variável automáticaNF
, será reconhecido como "zero". O programa (bem curto) acima impõe a condição queNF
deve ser diferente de zero para que ele imprima a linha atual. Isso remove efetivamente linhas vazias verdadeiras ou "visualmente".Como
awk
por padrão não executará edição em linha, você pode ter que recorrer ao redirecionamento da saída para um arquivo temporário e depois renomeá-lo ou usar uma implementação suficientemente recente que entenda a-i inplace
extensão:Aqui está outra abordagem portátil, que é incluir apenas linhas que contenham algo diferente de espaços em branco:
Você pode usar a mesma abordagem com outros comandos também:
Gravar no mesmo arquivo que a fonte é um procedimento bastante padrão. Alguns comandos usam
-i
(ou um equivalente) para indicar a edição no local , mas na prática eles gravam em um arquivo temporário e depois substituem o arquivo original pelo temporário:Isso funciona bem desde que
file
não tenha links físicos de outros lugares. Para atender a essas situações, você precisa de uma cópia dupla:Infelizmente, só posso reproduzir seu problema no macOS, onde
sed
entende\s
comos
. O padrão^\s*$
, portanto, corresponderia a qualquer linha consistindo em zero ou maiss
caracteres. Isso inclui linhas vazias, mas não linhas que contêm apenas caracteres tipo espaço.Uma maneira portátil de remover linhas vazias ou que contêm apenas espaços ou tabulações é
Isso usa
grep
para extrair apenas as linhas que não correspondem[[:blank:]]*
. O[[:blank:]]*
padrão corresponde a zero ou mais espaços ou caracteres de tabulação. Se você quiser corresponder a um conjunto maior de caracteres semelhantes a espaços (incluindo coisas como retornos de carro e guias verticais), use[[:space:]]*
em vez disso. A-x
opção paragrep
forçar o padrão a corresponder a linhas completas (como se você tivesse ancorado a expressão com^
e$
).Você pode simplesmente substituir o
\s
por[[:space:]]
. Além disso, a maioria dassed
versões tem um-i
sinalizador que significa editar o arquivo no local . Portanto, este comando deve funcionar:Testando isso em um sistema com ferramentas GNU; aqui, o
%
é o prompt do shell e o$
marcador de final de linha adicionado porcat -A
:Não há linhas vazias no final do arquivo resultante.
O fato de alguns editores permitirem mover o cursor sob a última linha para facilitar a adição de uma nova linha no final não está relacionado a como as linhas aparentemente vazias são removidas por esse comando sed.
(Em vez do pipe com
sponge
, você pode usar apenassed -i '/^\s*$/d' file.txt
, mas provavelmente deve usar[[:space:]]*
em vez de\s*
ser mais amplamente suportado.)Você poderia usar:
Que reportaria as linhas contendo pelo menos um caractere gráfico, excluindo assim as linhas que estão vazias ou consistem apenas em caracteres de espaço em branco, caracteres de controle, caracteres desconhecidos/indefinidos/inválidos.