web-dev-qa-db-fra.com

Comment supprimer des lignes vides d'un fichier Unix

Je dois supprimer toutes les lignes vides d'un fichier d'entrée et l'écrire dans un fichier de sortie. Voici mes données ci-dessous.

11216,33,1032747,64310,1,0,0,1.878,0,0,0,1,1,1.087,5,1,1,18-JAN-13,000603221321

11216,33,1033196,31300,1,0,0,1.5391,0,0,0,1,1,1.054,5,1,1,18-JAN-13,059762153003

11216,33,1033246,31300,1,0,0,1.5391,0,0,0,1,1,1.054,5,1,1,18-JAN-13,000603211032

11216,33,1033280,31118,1,0,0,1.5513,0,0,0,1,1,1.115,5,1,1,18-JAN-13,055111034001

11216,33,1033287,31118,1,0,0,1.5513,0,0,0,1,1,1.115,5,1,1,18-JAN-13,000378689701

11216,33,1033358,31118,1,0,0,1.5513,0,0,0,1,1,1.115,5,1,1,18-JAN-13,000093737301

11216,33,1035476,37340,1,0,0,1.7046,0,0,0,1,1,1.123,5,1,1,18-JAN-13,045802041926

11216,33,1035476,37340,1,0,0,1.7046,0,0,0,1,1,1.123,5,1,1,18-JAN-13,045802041954

11216,33,1035476,37340,1,0,0,1.7046,0,0,0,1,1,1.123,5,1,1,18-JAN-13,045802049326

11216,33,1035476,37340,1,0,0,1.7046,0,0,0,1,1,1.123,5,1,1,18-JAN-13,045802049383

11216,33,1036985,15151,1,0,0,1.4436,0,0,0,1,1,1.065,5,1,1,18-JAN-13,000093415580

11216,33,1037003,15151,1,0,0,1.4436,0,0,0,1,1,1.065,5,1,1,18-JAN-13,000781202001

11216,33,1037003,15151,1,0,0,1.4436,0,0,0,1,1,1.065,5,1,1,18-JAN-13,000781261305

11216,33,1037003,15151,1,0,0,1.4436,0,0,0,1,1,1.065,5,1,1,18-JAN-13,000781603955

11216,33,1037003,15151,1,0,0,1.4436,0,0,0,1,1,1.065,5,1,1,18-JAN-13,000781615746
43
Teja
sed -i '/^$/d' foo

Ceci dit à sed de supprimer toutes les lignes correspondant à la regex ^$ _ c'est-à-dire chaque ligne vide. Le -i flag édite le fichier sur place, si votre sed ne prend pas en charge le fait que vous pouvez écrire le résultat dans un fichier temporaire et remplacer le fichier d'origine:

sed '/^$/d' foo > foo.tmp
mv foo.tmp foo

Si vous souhaitez également supprimer les lignes composées uniquement d'espaces (et pas seulement de lignes vides), utilisez:

sed -i '/^[[:space:]]*$/d' foo

Edit: supprime également les espaces à la fin des lignes, car apparemment vous en avez décidé vous aussi:

sed -i '/^[[:space:]]*$/d;s/[[:space:]]*$//' foo
86
Jonathan Wakely
awk 'NF' filename
awk 'NF > 0' filename
sed -i '/^$/d' filename
awk '!/^$/' filename
awk '/./' filename

La NF supprime également les lignes ne contenant que des blancs ou des tabulations, la regex /^$/ ne fait pas.

36
Jotne

Utilisez grep pour faire correspondre toute ligne n’ayant rien entre l’ancre de départ (^) et l'ancre d'extrémité ($):

grep -v '^$' infile.txt > outfile.txt

Si vous souhaitez supprimer des lignes ne contenant que des espaces, vous pouvez toujours utiliser grep. J'utilise des expressions régulières Perl dans cet exemple, mais voici d'autres méthodes:

grep -P -v '^\s*$' infile.txt > outfile.txt

ou, sans expressions régulières Perl:

grep -v '^[[:space:]]*$' infile.txt > outfile.txt
15
gpojd
sed -e '/^ *$/d' input > output

Supprime toutes les lignes composées uniquement de blancs (ou est complètement vide). Vous pouvez changer le blanc en [ \t] où le \t est une représentation de tab. Que votre shell ou votre sed fasse l'expansion, mais vous pouvez probablement taper directement le caractère de tabulation. Et si vous utilisez GNU ou BSD sed, vous pouvez effectuer la modification sur place, si c'est ce que vous voulez, avec le -i option.


Si j'exécute la commande ci-dessus, j'ai toujours des lignes vides dans mon fichier de sortie. Quelle pourrait être la raison?

Il pourrait y avoir plusieurs raisons. Il se peut que vous n'ayez pas de lignes vierges, mais que vous ayez beaucoup d'espaces à la fin d'une ligne. Il semble donc que vous ayez des lignes vides lorsque vous affichez le fichier à l'écran. Si c'est le problème, alors:

sed -e 's/  *$//' -e '/^ *$/d' input > output

La nouvelle expression rationnelle supprime les espaces répétés à la fin de la ligne; voir la discussion précédente pour les blancs ou les onglets.

Une autre possibilité est que votre fichier de données provient de Windows et comporte des fins de ligne CRLF. Unix voit le retour de chariot à la fin de la ligne; ce n'est pas un blanc, donc la ligne n'est pas supprimée. Il y a plusieurs façons de gérer cela. Une solution fiable est tr à supprimer (-d) code de caractère octal 15, alias control-M ou \r ou retour chariot:

tr -d '\015' < input | sed -e 's/  *$//' -e '/^ *$/d' > output

Si aucune de ces méthodes ne fonctionne, vous devez afficher un vidage hexadécimal ou octal (od -c) des deux premières lignes du fichier, nous pouvons voir à quoi nous sommes confrontés:

head -n 2 input | od -c

A en juger par les commentaires que sed -i ne fonctionne pas pour vous, vous ne travaillez pas sous Linux, Mac OS X ou BSD - sur quelle plate-forme travaillez-vous? (AIX, Solaris et HP-UX me viennent à l’esprit comme des possibilités relativement plausibles, mais il en existe de nombreuses autres moins plausibles.)

Vous pouvez essayer les classes de caractères nommés POSIX telles que sed -e '/^[[:space:]]*$/d'; cela fonctionnera probablement, mais ce n'est pas garanti. Vous pouvez l'essayer avec:

echo "Hello World" | sed 's/[[:space:]][[:space:]]*/   /'

Si cela fonctionne, il y aura trois espaces entre le "Bonjour" et le "Monde". Sinon, vous obtiendrez probablement une erreur de sed. Cela vous évitera peut-être de devoir taper des onglets sur la ligne de commande.

12
Jonathan Leffler
grep . file

grep regarde votre fichier ligne par ligne; le point . correspond à tout sauf un caractère de nouvelle ligne. La sortie de grep correspond donc à toutes les lignes qui consistent en autre chose qu’une seule nouvelle ligne.

8
Ed Morton

avec awk

awk 'NF > 0' filename

5
Mirage

Vous pouvez sed's -i option pour éditer sur place sans utiliser de fichier temporaire:

 sed -i '/^$/d' file
2
P.P.

Pour être complet et supprimer les lignes paires si elles incluent des espaces ou des tabulations, quelque chose comme ça en Perl le fera:

cat file.txt | Perl -lane "print if /\S/"

Bien sûr, il existe les équivalents awk et sed. Mieux vaut ne pas supposer que les lignes sont totalement vierges comme ^$ ferait.

À votre santé

2
G. Cito