Caret recherche et remplace dans Bash shell

Si je viens de saisir la commande suivante dans Bash:

echo foo 

Je peux changer foo en bar en tapant:

 ^foo^bar 

Ce qui entraîne l’exécution de la commande suivante:

 echo bar 

Maintenant si j’entre:

 echo foo foo 

Est-il possible de changer les deux instances de foo en bar en utilisant simplement l’opérateur caret ( ^ )?

De plus, existe-t-il des pages de manuel pour les opérateurs de shell comme ^ ? man ^ traduit par “Pas d’entrée manuelle pour ^”.

Cette fonctionnalité particulière est appelée substitution rapide ; sa documentation se trouve dans la section Event Designators du manuel Bash. Vous ne pouvez pas faire ce que vous voulez avec une substitution rapide; vous devrez recourir à quelque chose de plus verbeux:

 !!:gs/foo/bar/ 

Vous ne savez pas non plus comment procéder avec la substitution au caret, mais voici comment vous le faites avec l’histoire:

 !!:gs/foo/bar/ 

Laissez-moi décomposer:

!! – relance la dernière commande. Vous pouvez également utiliser! -2 pour exécuter deux commandes, echo pour exécuter la dernière commande qui commence par echo

: gs dit de faire une recherche / remplacement globale (toutes les instances). Si vous vouliez simplement remplacer la première instance, vous utiliseriez ‘: s’

Enfin, / foo / bar / dit de remplacer foo par bar

Essayer:

 ^foo^bar^:& 

Comme vous le savez, ^foo^bar^ exécute une seule substitution, et le modificateur :& répète cette substitution.

La substitution de caret et d’autres raccourcis similaires se trouvent dans la sous-section Event Designators de la section HISTORY EXPANSION de la page de manuel bash(1) .

 ^word^ ........... erase word ^word^^ ........... delete everything until the end of the line 

Si vous cherchez quelque chose de moins difficile à mémoriser qui accomplit la même chose que ci-dessus !!:gs/foo/bar/ , vous pouvez toujours créer une fonction dans votre script de démarrage .bash_profile. J’ai choisi replace() .

 replace() { eval $(echo $(fc -ln -1) | eval "sed 's/${1}/${2}/g'") #compact form } 

OU, moins compliqué

 replace() { ssortingng=$(fc -ln -1) #gets last command ssortingng repcmmd="sed 's/${1}/${2}/g'" #build replacement sed command from fn input eval $(echo $ssortingng | eval $repcmmd) #evaluates the replacement command } 

Alors le tout peut être fait avec

 echo foo foo replace foo bar