Supprimez toutes les lignes qui n'ont pas n caractères avant le délimiteur

11

J'ai un très long fichier texte (d' ici ) qui devrait contenir 6 caractères hexadécimaux puis un 'break' (qui apparaît comme un caractère et ne semble pas apparaître correctement dans le code Markdown ci-dessous) suivi de quelques mots:

00107B  Cisco Systems, Inc
00906D  Cisco Systems, Inc
0090BF  Cisco Systems, Inc
5080    Cisco Systems, Inc
0E+00   ASUSTek COMPUTER INC.
000C6E  ASUSTek COMPUTER INC.
001BFC  ASUSTek COMPUTER INC.
001E8C  ASUSTek COMPUTER INC.
0015F2  ASUSTek COMPUTER INC.
2354    ASUSTek COMPUTER INC.
001FC6  ASUSTek COMPUTER INC.
60182E  ShenZhen Protruly Electronic Ltd co.
F4CFE2  Cisco Systems, Inc
501CBF  Cisco Systems, Inc

J'ai fait quelques recherches et je ne vois rien qui pourrait fonctionner dans cette situation. Ma question est, comment puis-je utiliser grep/ sed/ awk/ perlpour supprimer toutes les lignes de ce fichier texte qui ne commencent pas avec exactement 6 caractères hexadécimaux et ensuite un 'break'?

PS Pour les points bonus, quelle est la meilleure façon de trier le fichier par ordre alphabétique et numérique selon les caractères hexadécimaux (ie 000000-> FFFFFF)? Dois-je simplement utiliser sort?

Rocco
la source

Réponses:

13
$ awk '$1 ~ /^[[:xdigit:]]{6}$/' file
00107B  Cisco Systems, Inc
00906D  Cisco Systems, Inc
0090BF  Cisco Systems, Inc
000C6E  ASUSTek COMPUTER INC.
001BFC  ASUSTek COMPUTER INC.
001E8C  ASUSTek COMPUTER INC.
0015F2  ASUSTek COMPUTER INC.
001FC6  ASUSTek COMPUTER INC.
60182E  ShenZhen Protruly Electronic Ltd co.
F4CFE2  Cisco Systems, Inc
501CBF  Cisco Systems, Inc

Cela permet awkd'extraire les lignes qui contiennent exactement six chiffres hexadécimaux dans le premier champ. Le [[:xdigit:]]modèle correspond à un chiffre hexadécimal et {6}nécessite six d'entre eux. Avec l'ancrage au début et à la fin du champ avec ^et $respectivement, cela ne correspondra qu'aux lignes souhaitées.

Redirigez vers un fichier pour l'enregistrer sous un nouveau nom.

Notez que cela semble fonctionner avec GNU awk(communément trouvé sous Linux), mais pas avec awkpar exemple OpenBSD, ou mawk.


Une approche similaire avec sed:

$ sed -n '/^[[:xdigit:]]\{6\}\>/p' file
00107B  Cisco Systems, Inc
00906D  Cisco Systems, Inc
0090BF  Cisco Systems, Inc
000C6E  ASUSTek COMPUTER INC.
001BFC  ASUSTek COMPUTER INC.
001E8C  ASUSTek COMPUTER INC.
0015F2  ASUSTek COMPUTER INC.
001FC6  ASUSTek COMPUTER INC.
60182E  ShenZhen Protruly Electronic Ltd co.
F4CFE2  Cisco Systems, Inc
501CBF  Cisco Systems, Inc

Dans cette expression, \>est utilisé pour faire correspondre la fin du nombre hexadécimal. Cela garantit que les numéros plus longs ne correspondent pas. Le \>motif correspond à une limite de mot , c'est-à-dire l'espace de largeur nulle entre un caractère de mot et un caractère non-mot.


Pour trier les données résultantes, dirigez simplement le creux des résultats sort, ou sort -fsi vos nombres hexadécimaux utilisent des lettres majuscules et minuscules

Kusalananda
la source
1
Parfait, merci beaucoup. Exactement ce que je cherchais!
Rocco
8

Et pour être complet, vous pouvez aussi le faire avec grep:

$ grep -E '^[[:xdigit:]]{6}\b' oui.txt 
00107B  Cisco Systems, Inc
00906D  Cisco Systems, Inc
0090BF  Cisco Systems, Inc
000C6E  ASUSTek COMPUTER INC.
001BFC  ASUSTek COMPUTER INC.
001E8C  ASUSTek COMPUTER INC.
0015F2  ASUSTek COMPUTER INC.
001FC6  ASUSTek COMPUTER INC.
60182E  ShenZhen Protruly Electronic Ltd co.
F4CFE2  Cisco Systems, Inc
501CBF  Cisco Systems, Inc
$ 

Cette expression grep étendue recherche exactement 6 chiffres hexadécimaux au début de chaque ligne, suivie immédiatement par une frontière non-espace-à-espace ( \b).

Traumatisme numérique
la source