J'essaie d'utiliser une regex pour formater un binaire de xxd -b
, mais pour le démontrer simplement, je vais vous montrer ce que j'attends de se produire:
Regex à supprimer: /1x|1.*/
Texte: 1x21y3333333313333
-> 2
Où tout les occurrences de 1x
sont supprimées, puis tout ce qui commence au premier 1 qui apparaît doit être supprimé. Ce qui se passe devrait être immédiatement évident, mais sinon, jouez avec ça . La clé est que si 1x
correspond, le reste du modèle doit être abandonné.
Voici la sortie de echo "AA" | xxd -b
(le bindump de AA\n
):
0000000:100000110000010001010
Mon objectif est de 1. supprimer le premier 0 pour chaque byte (ascii = 7 bits) et 2. supprimez le reste de la chaîne pour ne conserver que le binaire réel. Je l'ai donc envoyé dans sed 's / 0 // g'
:
0000000:
Ajout de la deuxième étape, sed -E ' s / 0 | . * // g '
:
0000000:100000110000010001010 AA.
Évidemment, j'espère obtenir à la place:
0000000: 01000001 01000001 00001010 AA.
Choses J'ai essayé mais je n'ai pas fait le travail:
xxd
peut prendre -g0
pour fusionner les colonnes, mais il conserve le premier zéro dans chaque octet (les caractères occupent chacun un octet, pas 7 bits) li>
-r
Je vais utiliser perl à la place en attendant, mais ce comportement me déroute et peut-être qu'il y a une raison (leçon) ici?
3 Réponses :
Si je comprends bien votre question, cela produit ce que vous voulez:
$ echo "AA" | xxd -b | sed -E 's/ 0//g; s/ .*//' 00000000:100000110000010001010
Le changement clé ici est l'utilisation de deux espaces devant . *
donc que cela ne correspond qu'à la partie que vous souhaitez supprimer.
Sinon, nous pouvons d'abord supprimer le blanc-zéro:
$ echo "AA" | xxd -b | sed -E 's/ 0| .*//g' 00000000:100000110000010001010
J'aime le deuxième extrait, ça m'a fait me gifler. Au lieu de faire les alternances dans une regex, je pourrais simplement la diviser!
Essayez ce qui suit:
s/ 0| [^0].*//g
La raison du comportement observé est que POSIX ordonne aux moteurs de suivre la norme de correspondance la plus longue possible . Donc, tant que le deuxième côté de l'alternance est plus long que le premier, même en étant le deuxième dans l'ordre, il correspond plus tôt.
Oh mon dieu, tu as raison. Après avoir recherché "posix plus longue correspondance" et parcouru deux liens, il est apparemment indiqué ici : "Si le modèle permet un nombre variable de caractères correspondants et qu'il y a donc plus d'une séquence de ce type à partir de ce point, la plus longue séquence de ce type est mise en correspondance. [...] l'ERE" (wee | week ) (knights | night) "correspond aux dix caractères de la chaîne" weeknights "." Certainement contre-intuitif après avoir utilisé beaucoup de regex modernes ...
Bien que cette réponse corresponde à la chaîne d'entrée donnée, elle échouera si une séquence démarre, par ex. avec 1
. La bonne façon est la deuxième approche de John1024.
@revo Ma mise à jour de stackoverflow.com/a/216228/6309 n'était pas assez complète?
@VonC C'était. Je voulais attirer plus d'attention pour impliquer plus de gens. Malheureusement, j'ai oublié de donner la prime en fin de période.
essayé sur gnu sed
sed -E 's/\s+(0|[a-z.]+)//ig'