La façon normale de procéder consiste à utiliser des barres obliques, mais cela peut devenir fastidieux si vous recherchez et remplacez quelque chose par des barres obliques. Ce n'est pas le cas ici, donc même si c'est très bien, cela déroute les futurs mainteneurs comme vous.
Thorbjørn Ravn Andersen
2
… Et les amène à apprendre quelque chose de nouveau sur sedce chemin! :)
dessert
Réponses:
15
Dans sed, les commandes de substitution sont généralement écrites sous la forme s/pattern/replacement/options. Cependant, il n'est pas nécessaire d'utiliser /- vous pouvez utiliser d'autres caractères si cela vous convient, ce pourrait donc être s@pattern@replacement@optionsou s:foo:bar:g. s@+@ @gc'est comme s/+/ /g- remplacer tout +par des espaces. De même s@%@\\x@gremplace tous %avec \x(une seule barre oblique inverse est un caractère d'échappement à sed, vous avez donc besoin de deux pour obtenir une barre oblique inverse réelle).
Une chaîne comme foo+%2Fbardeviendra alors foo \x2Fbar. printf "%b"étendra les séquences échappées par une barre oblique inverse comme \x2F(le caractère ASCII dont la valeur hexadécimale est 2F, qui est /) pour enfin vous donner foo /bar.
Vous pouvez être plus habitué à le voir avec /plutôt que @comme séparateur, ce qui aurait facilement pu être fait ici sans complication car il /n'apparaît dans aucun des modèles de recherche ni dans aucun des textes de remplacement. Cette commande est équivalente:
sed 's/+/ /g;s/%/\\x/g'
Comme /, @est un caractère de ponctuation parfaitement bon pour sed.
Sur chaque ligne d'entrée:
s@+@ @g( s/+/ /g) substitue ( s) les occurrences de +avec un espace. Cela affecte tous les +es sur une ligne ( g), pas seulement le premier.
; termine l'action ("commande") et vous permet d'en spécifier une autre dans le même "script".
s@%@\\x@g( s/%/\\x/g) substitue ( s) les occurrences de %avec \x. Comme précédemment, il agit sur tous plutôt que sur la première de chaque ligne ( g).
Dans \\xle \\représente un seul \car \a une signification particulière pour sed. Sa signification spéciale est en fait le personnage que vous utilisez pour enlever la signification spéciale d'un autre personnage qui vient après lui qui aurait autrement une signification spéciale. Il faut donc échapper comme \\.
Regardons maintenant une xargscommande dont le but est de s'exécuter printf.
xargsconstruit des lignes de commande. Si vous exécutez , où est un ou plusieurs mots, s'exécute avec des arguments de ligne de commande supplémentaires lus à partir de son entrée. Dans ce cas, l'entrée de est la sortie de , en raison de pipe ( ). Interprète normalement tout espace dans son entrée pour signifier que le texte avant et après il constitue des arguments séparés, mais l' option le fait fractionner les arguments à la place du caractère nul .xargs command...command...xargscommand...xargssed|xargs-0
Dans l'utilisation prévue de votre commande, un caractère nul n'apparaîtra pas et xargss'exécutera printf %bavec un seul argument de ligne de commande supplémentaire, la sortie de la sedcommande. Ainsi, bien qu'il ne soit pas équivalent en général, dans ce cas, l'ensemble du pipeline aurait pu être écrit comme ceci en utilisant la substitution de commandes au lieu de xargs:
printf '%b\n'"$(sed 's/+/ /g;s/%/\\x/g')"
Quant à ce qui printfest prévu ici, comme le dit muru, le %bspécificateur de format consomme et imprime un argument (comme %s) mais provoque des échappements de barre oblique inverse - du type que la sedcommande sur le côté gauche du tuyau a été écrit pour générer - à traduire dans les personnages qu'ils représentent .
Supposons que j'exécute cette commande et passe http://foldoc.org/debugging%20by%20printfen entrée. J'obtiens http://foldoc.org/debugging by printfen sortie, car les %20séquences sont traduites en espaces.
C'est la beauté de sed, il applique ses paradigmes à lui-même ... Après la commande (comme sou trou rien), le personnage suivant est considéré comme le séparateur.
Vous devez choisir judicieusement pour éviter les interférences avec le shell et la commande elle-même, et garder la chose lisible, mais il est parfaitement valable d'écrire quelque chose d'aussi horrible que:
echo 'arrival' | sed srarbrg
... et obtenez brrivblen conséquence, ce que vous attendez. Vous pouvez vous amuser à le rendre vraiment cryptique, comme dans:
echo 'arrival' | sed s\fa\fb\fg # \f is form feed, chr(12)
L'utilisation courante consiste à utiliser la barre oblique comme délimiteur, mais lorsque votre expression contient le délimiteur, il est plus facile de saisir l'intention. Votre délimiteur peut être n'importe quoi dans la plage ASCII8 (délimiteurs multi-octets tels que £provoquer une erreur).
N'oubliez pas que l'objectif est de rendre les choses plus faciles, pas plus cryptiques.
Fonctionnant avec l'idée cryptique, il s'agit d'une commande sed valide, bien qu'elle ne fasse rien d'utile:sed "snack is an apple or something" <<< "I sed your snack is an apple or something"
wjandrea
Agréable! Oui, vous pouvez également utiliser des sedcommandes comme casse-tête, comment est-ce geek?
sed
ce chemin! :)Réponses:
Dans sed, les commandes de substitution sont généralement écrites sous la forme
s/pattern/replacement/options
. Cependant, il n'est pas nécessaire d'utiliser/
- vous pouvez utiliser d'autres caractères si cela vous convient, ce pourrait donc êtres@pattern@replacement@options
ous:foo:bar:g
.s@+@ @g
c'est commes/+/ /g
- remplacer tout+
par des espaces. De mêmes@%@\\x@g
remplace tous%
avec\x
(une seule barre oblique inverse est un caractère d'échappement à sed, vous avez donc besoin de deux pour obtenir une barre oblique inverse réelle).Une chaîne comme
foo+%2Fbar
deviendra alorsfoo \x2Fbar
.printf "%b"
étendra les séquences échappées par une barre oblique inverse comme\x2F
(le caractère ASCII dont la valeur hexadécimale est 2F, qui est/
) pour enfin vous donnerfoo /bar
.la source
La commande pour laquelle vous demandez le décodage des
+
es et des%
séquences des URL n'est pas seulement unesed
commande, c'est un pipeline qui traite les entrées avecsed
, puis les redirige versxargs
un traitement ultérieur. Voyons d'abord lased
commande:Vous pouvez être plus habitué à le voir avec
/
plutôt que@
comme séparateur, ce qui aurait facilement pu être fait ici sans complication car il/
n'apparaît dans aucun des modèles de recherche ni dans aucun des textes de remplacement. Cette commande est équivalente:Comme
/
,@
est un caractère de ponctuation parfaitement bon poursed
.Sur chaque ligne d'entrée:
s@+@ @g
(s/+/ /g
) substitue (s
) les occurrences de+
avec un espace. Cela affecte tous les+
es sur une ligne (g
), pas seulement le premier.;
termine l'action ("commande") et vous permet d'en spécifier une autre dans le même "script".s@%@\\x@g
(s/%/\\x/g
) substitue (s
) les occurrences de%
avec\x
. Comme précédemment, il agit sur tous plutôt que sur la première de chaque ligne (g
).Dans
\\x
le\\
représente un seul\
car\
a une signification particulière poursed
. Sa signification spéciale est en fait le personnage que vous utilisez pour enlever la signification spéciale d'un autre personnage qui vient après lui qui aurait autrement une signification spéciale. Il faut donc échapper comme\\
.Regardons maintenant une
xargs
commande dont le but est de s'exécuterprintf
.xargs
construit des lignes de commande. Si vous exécutez , où est un ou plusieurs mots, s'exécute avec des arguments de ligne de commande supplémentaires lus à partir de son entrée. Dans ce cas, l'entrée de est la sortie de , en raison de pipe ( ). Interprète normalement tout espace dans son entrée pour signifier que le texte avant et après il constitue des arguments séparés, mais l' option le fait fractionner les arguments à la place du caractère nul .xargs command...
command...
xargs
command...
xargs
sed
|
xargs
-0
Dans l'utilisation prévue de votre commande, un caractère nul n'apparaîtra pas et
xargs
s'exécuteraprintf %b
avec un seul argument de ligne de commande supplémentaire, la sortie de lased
commande. Ainsi, bien qu'il ne soit pas équivalent en général, dans ce cas, l'ensemble du pipeline aurait pu être écrit comme ceci en utilisant la substitution de commandes au lieu dexargs
:Quant à ce qui
printf
est prévu ici, comme le dit muru, le%b
spécificateur de format consomme et imprime un argument (comme%s
) mais provoque des échappements de barre oblique inverse - du type que lased
commande sur le côté gauche du tuyau a été écrit pour générer - à traduire dans les personnages qu'ils représentent .Supposons que j'exécute cette commande et passe
http://foldoc.org/debugging%20by%20printf
en entrée. J'obtienshttp://foldoc.org/debugging by printf
en sortie, car les%20
séquences sont traduites en espaces.la source
C'est la beauté de
sed
, il applique ses paradigmes à lui-même ... Après la commande (commes
outr
ou rien), le personnage suivant est considéré comme le séparateur.Vous devez choisir judicieusement pour éviter les interférences avec le shell et la commande elle-même, et garder la chose lisible, mais il est parfaitement valable d'écrire quelque chose d'aussi horrible que:
... et obtenez
brrivbl
en conséquence, ce que vous attendez. Vous pouvez vous amuser à le rendre vraiment cryptique, comme dans:L'utilisation courante consiste à utiliser la barre oblique comme délimiteur, mais lorsque votre expression contient le délimiteur, il est plus facile de saisir l'intention. Votre délimiteur peut être n'importe quoi dans la plage ASCII8 (délimiteurs multi-octets tels que
£
provoquer une erreur).N'oubliez pas que l'objectif est de rendre les choses plus faciles, pas plus cryptiques.
la source
sed "snack is an apple or something" <<< "I sed your snack is an apple or something"
sed
commandes comme casse-tête, comment est-ce geek?