2010-01-27 18 views
39

Si Me acaban de entrar en el siguiente comando en Bash:Caret buscar y reemplazar en Bash shell

echo foo 

puedo cambiar foo a bar escribiendo:

^foo^bar 

lo que se traduce en el siguiente comando siendo ejecutado:

echo bar 

Ahora si entro:

echo foo foo 

¿Hay alguna manera de cambiar ambas instancias de foo a la barra simplemente usando el operador caret (^)?

Además, ¿hay páginas man para operadores de shell como ^? man ^ resultados en "Sin entrada manual para ^".

+2

Gracias por las respuestas, estaba esperando una manera de utilizar el^sintaxis para los duplicados desde es algo que puedo recordar más fácilmente, pero parece que tendré que memorizar la versión de ruido de línea. – mattjames

+1

Puede que le resulte más fácil recordar la versión de "ruido de línea" si también piensa en '^ string1^string2' como si fuera equivalente a' !!: s/string1/string2/'. – isomorphismes

+0

@mattjames si quiere algo más fácil de recordar, puede verificar mi respuesta, que es menos "ruido de línea" -y – MLP

Respuesta

48

Esa característica particular se llama sustitución rápida ; su documentación se puede encontrar en la sección Event Designators del Manual de Bash. No puedes hacer lo que quieras con una sustitución rápida; vas a tener que recurrir a algo un poco más detallado:

!!:gs/foo/bar/ 
+0

@scanny: Eso no parece estar documentado en ninguna parte, y no funciona para mí en bash 4.2.10 (1). ¿Qué versión del shell estás usando ('bash --version')? –

+0

Vaya, mi error, 'zsh' en el cerebro! : S borró el comentario. – scanny

+0

La barra inclinada no fue necesaria para mí en OSX: '!!: gs/foo/bar' –

27

Tampoco seguro de cómo hacerlo con la sustitución de intercalación, pero aquí es como lo haces con la historia:

!!:gs/foo/bar/ 

Vamos a dividirla que abajo:

!! - vuelve a ejecutar el último comando. También puede usar! -2 para ejecutar dos comandos atrás,! Echo para ejecutar el último comando que comienza con echo

: gs dice que haga una búsqueda/reemplazo global (todas las instancias). Si quería simplemente reemplazar el primer caso, se usaría ': s'

Finalmente,/foo/bar/dice para sustituir foo con bar

5

Caret sustitución y otros accesos directos similares se encuentran en el designadores de eventos subsección de la sección historia de la expansión de la páginabash(1) hombre.

1
^word^ ........... erase word 
^word^^ ........... delete everything until the end of the line 
+3

Ambos hacen lo mismo por mí: elimine solo la palabra del comando. –

+0

Lo mismo aquí. '% Echo "palabra palabra palabra palabra palabra" palabra palabra palabra palabra palabra %^palabra ^^ echo "palabra palabra palabra palabra" palabra palabra palabra palabra' – isomorphismes

21

Probar:

^foo^bar^:& 

Como saben ^foo^bar^ realiza sólo una sustitución, y el modificador :& lo repite.

+9

Esto ejecutará dos sustituciones, pero no un cambio global. – isomorphismes

+2

Descubrí que podía pasar múltiples modificadores ": &" a la sustitución de intercalación. Entonces, ": &" significa nuevamente, y ": &: &" significa nuevamente dos veces, y así sucesivamente. (Repetir: ¡¡y para cada repetición se volverá tedioso y me alegra aprender !!: gs //. – rickumali

0

Si está buscando algo menos difícil de memorizar que logra lo mismo que el anterior !!:gs/foo/bar/, siempre puede crear una función en su script de arranque .bash_profile. Elegí replace().

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

o, menos convolutedly

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

A continuación, la sustitución de todo se puede hacer con

echo foo foo 
replace foo bar