He copiado el comando cd C:\foo\bar\
de PowerShell a Cygwin y Sillily esperaba que se ejecutara. Ahora estoy tratando de ejecutar una sustitución para reemplazar todos los \
con /
:
$ !!:gs/\\/\/
bash: :gs/\\/\/: substitution failed
No estoy seguro de por qué estoy recibiendo la sustitución fallida.
También intenté:
$ !!:gs/\\/q
Sólo para ver si el reemplazo fue el problema. No es. ¡Ahora estoy curioso!
¿Por qué estoy recibiendo "sustitución fallida"?
cd 'C:\foo\bar'
!!:gs/\\/\/
funciona en zsh ...fc -s '\'='/' -1
funciona bajo el bash predeterminado de Ubuntu LTS. Déjame saber si funciona bajo Cygwin también. Publiqué más palabras en la respuesta.!!:gs/\\/\//
. @Hastur'sfc -s '\'='/' -1
Obtiene el comportamiento esperado. esto podría ser un error en bash.Respuestas:
una barra diagonal hacia delante también es el delimitador de su comando de sustitución, por lo que debe escapar como una cadena de reemplazo para no finalizar la sustitución antes de tiempo
o más claramente como se sugiere en los comentarios, usando algo además de la barra como el delimitador
Pero esto solo parece funcionar en
tcsh
(el shell asignado comúnmente donde estoy), no puedo obtener el comando para trabajar enbash
Como parece escapar, no funciona en el primer argumento de:s
fuente
!!:gs|\\|/
podría ser un poco más legible.:s
no parece ser un regex realRespuesta corta: la incorporada
fc
(arreglar comando) de bashfc
es el comando, incorporado en el shell bash, hecho para editar & amp; volver a ejecutar los comandos de la historia.Es Presente en CygWin también y funciona en todas las distribuciones de Linux en las que he probado:
Algunas explicaciones
fc
es la fiesta incorporado mando para listar o editar y volver a ejecutar comandos de la lista de historial.-1
Tomará el último comando en la historia. Tenga en cuenta que incluso!!
está definido (leído deman bash
) como-s
Sustituir un patrón por otro. Esta vez dehelp fc
(comando incorporado parahelp
):Ok ellos quieren decir
pat=rep
en lugar deOLD=NEW
...'\'
y'/'
.Algunas palabras más acerca de por qué está obteniendo "sustitución fallida"
Parece que para el
s
modificador no se ha implementado (todavía) la sustitución del carácter de barra invertida\
, ese es el escape. Para asegurarnos de que deberíamos ver el código, por ejemplo, de la versión gnu de la expansión del historial de bash (pero estaba el comando anterior para obtener lo que estaba intentando hacer ... así que tómalo perezoso ....).Algunas notas:
Nos llevan a pensar que funcionará cada RegEx que encontremos trabajando con
sed
, pero no está garantizado. La barra invertida es el carácter de escape de la expansión y el problema está aquí. Además, el comportamiento de la expansión está relacionado con lashopt
Opciones, por lo que deberíamos empezar a ver caso por caso ...Cuando pegas la cadena
cd C:\Foo\Bar
en su shell bash se ampliará y aparecerá para el intérprete comocd C:FooBar
; de esta forma se almacenará en el$_
variable interna también.Si en lugar de pegar
cd "C:\Foo\Bar"
ocd 'C:\Foo\Bar'
en el$_
variable que deberías encontrarC:\Foo\Bar
.Dado que la expansión del Historial se realiza inmediatamente después de leer una línea completa, antes de que el shell la rompa en palabras, puede tener la tentación de comenzar a usarla con algunos bashismo más o menos simple, por ejemplo, con alguna derivación de (tal vez agregando
:p
o:q
,""
, analizando y así sucesivamente ...)Este es el momento para recordar que no es seguro. para comenzar jugar con camino y nombres de archivos , especialmente si vienen del portapapeles de Windows (lea en general la página Por qué no analizar gramaticalmente
ls
? , está esencialmente relacionado con la posibilidad de usar tabulaciones, espacios y nuevas líneas como caracteres correctos para los nombres de archivo y los de directorio ...).Además cuando Pegar un texto capturado con el ratón. , también puedes pegar un espacio inicial. Esto puede evitar que su comando termine en el historial (depende de las opciones de shell ...). Si es así tu siguiente
!!
será un comando no controlado ... (ver un ejemplo en otra respuesta ). Este es un riesgo tangible innecesario. .Conclusión
Si no es fácil empiezo a pensar que estamos haciendo algo mal.
;-)
Ad nauseam: un pequeño experimento.
He habilitado
histverify
en la cáscara entonces ...entonces presiono Entrar y como verificado expansión encuentro
entonces presiono Entrar de nuevo y se hace eco
Esto parece indicar que la
substitution failed
Se genera en la historia la expansión procesada antes de la Expansión de la abrazadera , asi que ante todo , y parece confirmar que las
el modificador de historia (todavía) no procesó la sustitución del\
personaje como regex real ...fuente
Puedes usar
sed
Sustituir y ejecutar el resultado.Hay varias variantes posibles para este comando, pero en mi caso solo este funcionó:
los
\\
se agrega a la!!
es en el caso de que el último comando terminó con una barra invertida Sin ella, la concha se confundirá y pedirá la continuación. de la linea.También puede agregar esto como una función bash en el archivo
~/.bashrc
:Aquí es cómo funciona esto en mi Bash en Windows:
Para explicar cómo el
A=
comando asigna el valor correcto a la variable de shellA
:tail
toma las dos últimas líneas del historial de comandos, lo que da la líneas decd \mnt\c
seguido porslash
sí mismo. La parte dehistory | tail -n 2
también puede ser escrito comohistory 2
.head
tomar la primera línea que escd \mnt\c
cut
corta el número de línea suministrado porhistory
sed
Reemplaza todos los anti-slashes por slasheseval
Ejecuta los contenidos de la variable.A
fuente
A=$(echo "!!\\" | sed 's,\\,/,g');eval $A
no funciona cuando el comando terminó con una barra invertida. Se te obliga a agregar un espacio, por ejemplo. aC:\Foo\Bar\
más, como dijiste, el shell esperará la continuación de la línea. También puedes pulsar enter dos veces. En el primer caso obtienesC:/Foo/Bar /
(con un espacio antes de la/
; En el segundo generará un error. La función funciona bien.No creo que puedas hacer esto. Necesitas copiar / pegar de nuevo.
El problema no está relacionado con la barra inclinada, sino también con el separador de comando de sustitución, ya que el comando de sustitución acepta cualquier separador. El problema es sobre las barras diagonales que se sustituirán, que ya han sido tratadas como simples escapes de caracteres inútiles a su derecha.
Por lo tanto, cuando llama al comando de sustitución, la barra invertida ya ha desaparecido de la fuente. Solo intente volver a llamar el comando tal como está (
!!
). En lugar de imprimir el mismo comando exacto incluyendoc:\foo
, ejecutará el comando menos las barras invertidas ya procesadas que resultan enc:foo
.Y obviamente no puedes encontrar ni reemplazar un personaje perdido. Tratar de hacerlo disparará un error.
fuente
echo c:\Foo
seguido por!!:gs,F,\\f,
. Pero Sustituir el escape de barra invertida en sí parece ser un dolor.