Awk : Delete comment lines and empty lines from a file

Bonjour mesdames, messieurs.

J’essayais de faire une truc simple avec awk - Le langage de programmation spécialisé dans le traitement de fichier texte :

Supprimer les lignes de commentaires et ligne vide d’un fichier.

Le fichier : cat ipv4-flood-20220223.txt

# 20220223

1.2.3.4
5.6.7.8
9.0.1.2

J’ai fais cela :

Supprimer les lignes de commentaires :
awk '!/^\#/ { print $0 }' ipv4-flood-20220223.txt

Alors j’ai écris cela pour supprimer les lignes vides :
awk '!/^\#/ || !/^$/ { print $0 }' ipv4-flood-20220223.txt

  1. Soit (par négation) la ligne commence par un dièse « # »,
  2. Soit (par négation) la ligne est vide.
  3. J’affiche les autres :smiley:

 

14:11:16 root@lab3w:~ # awk '!/^\#/ || !/^$/ { print $0 }' ipv4-flood-20220223.txt
# 20220223

1.2.3.4
5.6.7.8
9.0.1.2

Vu que çà me sortait quelque chose - de faux - j’ai écris cela :
cat ipv4-flood-20220223.txt | awk -- '!/^\#/ { print $0 }' | sed '/^$/d'

14:14:18 root@lab3w:~ # cat ipv4-flood-20220223.txt | awk -- '!/^\#/ { print $0 }' | sed '/^$/d'
1.2.3.4
5.6.7.8
9.0.1.2

Je souhaitais utiliser seulement awk avec plusieurs vérifications.

J’ai essayé cela :
awk '!/^\#/ && !/^$/ { print $0 }' ipv4-flood-20220223.txt

Et hop çà fonctionne !

14:15:01 root@lab3w:~ # awk '!/^\#/ && !/^$/ { print $0 }' ipv4-flood-20220223.txt
1.2.3.4
5.6.7.8
9.0.1.2

Pourtant la ligne ne pas commencer à la fois par un dièse « # » ET à la fois (commencer) être vide :confused: bizarre !


J’ai déjà remarqué cela - Et criez fort (mais gentillement) aux développeurs PHP et JavaScript dans l’espace, la Vie - mais pas dans le vent :wink: en faisant marcher leur logique.

Ils m’ont dit… oui Romain tu as raison !

Qu’en pensez-vous ? Vous… :slight_smile:

Bise :wink:
Bonne fin d’journée à vous !

Cordialement,
Romain.

J’ajoute un super lien Français : Traitement de fichiers texte en ligne de commande sous Linux :slight_smile:

Sans la négation çà fonctionne logiquement !

15:11:16 root@lab3w:~ # awk '/^\#/ || /^$/ { print $0 }' ipv4-flood-20220223.txt
# 20220223

15:35:57 root@lab3w:~ # awk '/^\#/ && /^$/ { print $0 }' ipv4-flood-20220223.txt
15:36:07 root@lab3w:~ #

:confused: Bizarre !

Salut,

d’après la doc, dans le cadre d’un « matching » par groupe (ce qui est nécessaire pour matcher une ligne vide, par le groupe (^$) ), l’opérateur OU est |

sputnik@debian:~/tests$ cat fichier
# 20220223

1.2.3.4
5.6.7.8
9.0.1.2
sputnik@debian:~/tests$ awk '!/(^$)|(#)/ {print $0}' fichier
1.2.3.4
5.6.7.8
9.0.1.2
sputnik@debian:~/tests$
1 J'aime

Bonjour,
Rien ne me choque dans le comportement, la reponse de awk est logique. Vous ne voulez pas les lignes qui contiennent # et ^$
Dans les negations, nous sommes plus souvent avec des ET que des OU sinon elles s’excluent mutuellement.

awk '!/(^$)|(^#)/ {print $0}' fichier

oui :smiley: :wink: :stuck_out_tongue_winking_eye: Merci d’avoir résolu ma demande @Sputnik93 !

Mais sinon… pensez à çà - au sujet :smiley:

Bonne soirée m’sieur !

mmmHouais ? haha :rofl: Merci messieurs, dames !

Screenshot 2022-02-23 at 16-54-08 Awk Delete comment lines and empty lines from a file - Programmation - debian-fr.org

Youpi :slight_smile: :heart: :wink:

Je ne trouve pas ça bizarre non plus.

C’est le comportement attendu: tu lui demande d’afficher les lignes qui commencent par un dièse (^\#) ou les lignes qui sont vides (^$). Donc il t’affiche toutes les lignes qui remplissent l’une ou l’autre de ces conditions.

C’est là aussi le comportement attendu, tu lui demandes d’afficher les lignes qui à la fois (&&) commencent par un dièse, et sont vides. Il ne t’affiche logiquement rien car aucune ligne ne peut réunir ces deux conditions.

Je pense que tu te méprends sur le sens des opérateurs logiques utilisés ici, et que tu penses que le OU est exclusif et que le ET est « laxiste » (je ne connais pas le terme), alors que ce n’est pas le cas.

Comme le dit la blague, quand on demande à un logicien d’apporter du vin rouge ou du vin blanc, il apporte les deux.

Bonjour.

Certes…

Là ok je suis d’accord - comme je l’ai écris.

Je disais quand on met une négation, une double négation - dans le sujet - pas dans mon 1er commentaire.

Cordialement,
Romain.

Bonne journée.

awk …ou sed

sed '/#\|^$/d' ipv4-flood-20220223.txt

ou encore plus simple:

grep '\.' ipv4-flood-20220223.txt

2 J'aime

Salut.

:wink: oui si tu veut trouver les lignes qui contiennent « un point » - ce n’est pas le sujet !

je comprends pas la commande.
en tout cas, ça me donne un résultat étrange avec :

# see "man logrotate" for details

# global options do not affect preceding include directives

# rotate log files weekly
weekly

# keep 4 weeks worth of backlogs
rotate 4

# create new (empty) log files after rotating old ones
create

# use date as a suffix of the rotated file
#dateext

# uncomment this if you want your log files compressed
#compress

# packages drop log rotation information into this directory
include /etc/logrotate.d

# system-specific logs may also be configured here.

on peut aussi utiliser grep :

grep -v '^\s*$\|^#\|^\s*\#'  /etc/logrotate.conf
grep -v -e '^\s*$' -e  '^#' -e '^\s*\#'  /etc/logrotate.conf

je ne sais pas quel outil est le plus efficace pour ce type d’opération ?
en tout cas, ma commande grep semble un peu plus rapide sur mes tests

Impossible / gros problème système à revoir.

$ cat ipv4-flood-20220223.txt
# 20220223

1.2.3.4
5.6.7.8
9.0.1.2

$ grep '\.' ipv4-flood-20220223.txt
1.2.3.4
5.6.7.8
9.0.1.2

ravi de l’apprendre

j’'obtiens le même résultat que toi avec ton exemple mais
t’as essayé avec le fichier que j’ai donné ?
pas très concluant

ça me donne un résultat étrange avec

Si non seulement tu changes de fichier test, sans préciser quel résultat étrange tu obtiens, ça complique effectivement.

grep -P '^\w' ipv4-flood-20220223.txt
1.2.3.4
5.6.7.8
9.0.1.2

grep -P '^\w' /etc/logrotate.conf
weekly
rotate 4
create
include /etc/logrotate.d

sed '/#\|^$/d' /etc/logrotate.conf
weekly
rotate 4
create
include /etc/logrotate.d`

En conclusion, quand on passe 4 jours sur une commande pour faire une opération extrêmement basique, c’est que awk n’était pas la bonne commande pour cette opération.

assez simple, je trouve que c’est une bonne solution.

J’avais en tête le traitement d’un fichier au format INI de manière générale.

Comme le titre concerne awk, et en synthèse:

$ TEXT='# comment\n\n1.2.3.4\n#\n\ntest suppression lignes inutiles\n'
$ printf $TEXT
# comment

1.2.3.4
#
test suppression lignes inutiles

Solutions:

$ printf $TEXT | awk '!/#|^$/'
$ printf $TEXT | sed '/#\|^$/d'
$ printf $TEXT | grep -P '^\w' 
$ printf $TEXT | grep -v '#\|^$'
1.2.3.4
test suppression lignes inutiles

Théorème de De Morgan
/(A+B) = /A . /B
/(A.B) = /A + /B

Il n’ y a pas plus de et que de ou mais une dualité entre les deux.

Attention avec le « et » et le « ou » lorsqu’il s’agit d’un énoncé en français: ex. je vais en France et en Islande. D’un point de vue logique cette proposition est toujours fausse car on ne peut pas être à la fois en France et en Italie.

Oui :smiley: :wink: Merci. C’est pour cela que j’aime la langue française :slight_smile: