grep pour les lignes avec un point-virgule dans unix

J’essaie d’obtenir des informations de disque à partir de la sortie de fdisk -l sur Linux.

 fdisk -l | grep -E 'Disk /dev/sd.\:' 

Je reçois la sortie suivante.

 Disk /dev/sde doesn't contain a valid partition table Disk /dev/sda: 1000.2 GB, 1000204886016 bytes Disk /dev/sdb: 1000.2 GB, 1000204886016 bytes 

mais ce que je veux obtenir est

 Disk /dev/sda: 1000.2 GB, 1000204886016 bytes Disk /dev/sdb: 1000.2 GB, 1000204886016 bytes 

J’ai essayé de faire ça

 fdisk -l | grep -E 'Disk /dev/sd.\:' | grep -v "contain" 

mais je ne sais pas pourquoi grep n’ignore pas la ligne contenant “contenir”.

Essayez cette commande:

 fdisk -l 2>/dev/null | grep -E 'Disk /dev/sd.\:' 

Ou simplement:

 fdisk -l 2>/dev/null 

Le problème est que la ligne Disk /dev/sde doesn't contain a valid partition table est générée en tant qu’erreur et écrite sur stderr au lieu de stdout .

Pipe in Unix uniquement les canaux de sortie écrits sur stdout partir de la commande précédente avec la commande sur RHS de pipe, donc votre commande grep ne fonctionne que sur les 2ème et 3ème lignes tandis que la 1ère ligne de votre terminal provient de stderr .

Toutes les commandes unix ont deux sorties; stderr et stdout. Les erreurs sont imprimées sur stderr et la sortie normale sur stdout. Dans votre exemple, vous pouvez envoyer stderr à / dev / null pour vous débarrasser de la ligne supplémentaire. Comme ça:

fdisk -l 2>/dev/null

Votre grep d’origine ne fonctionne pas car le message d’erreur relatif à “aucune partition valide” est écrit dans stderr . La solution consiste à redirect stderr vers stdout puis à le grep. Selon le shell, la commande variera.

Par exemple, csh / tcsh:

  fdisk -l |& grep -E 'Disk /dev/sd.\:' | grep -v "contain" 

sh / bash:

  fdisk -l 2>&1 | grep -E 'Disk /dev/sd.\:' | grep -v "contain" 

REMARQUE : redirect / supprimer tout stderr vers /dev/null est dangereux, car tous les messages d’erreur (attendus ou non ) y parviendront. Beaucoup plus sûr de combiner stderr et stdout et de traiter ce stream de manière sélective.