Es un buen hábito entrar para citar sus variables. El script de Shell es un lenguaje extraño que evolucionó con el tiempo en lugar de estar perfectamente diseñado desde el principio, por lo que desafortunadamente se hacen necesarias algunas cosas molestas como esta. Sin citar sus variables, los espacios en blanco o los asteriscos en el contenido de las variables harán que las cosas se rompan de manera extraña. Para hacer que sus scripts sean más robustos, siempre rodee los usos de sus variables con comillas dobles. Aquí, usted diría for filePng in "$folder"/*y touch "$filePng".txt , tenga en cuenta que solo los cita cuando está precedido por a $.
Muzer
3
Esto parece un problema XY ... ¿Por qué estás tratando de hacer esto?
JeromeJ
Respuestas:
16
Puedes usar el basenamecomando aquí:
touch "$folder/$(basename "$filePng" .png).txt"
Tenga en cuenta el adicional $folder/. Esto es necesario ya que el comando basename elimina la ruta de.
¿Puedo sugerirle que citó la expansión de sus parámetros y la sustitución de comandos?
Tom Fenech
@TomFenech, sí, probablemente sea una buena idea citar toda la cadena. Edité mi respuesta.
Wayne_Yux
No estoy seguro de por qué eliminó las comillas internas $filePng, también fueron útiles.
Tom Fenech
1
No, porque $( )establece un nuevo contexto de citas.
Tom Fenech
2
Oh, tienes razón, aprendí algo nuevo hoy ;-)
Wayne_Yux
31
Puede eliminar la extensión existente utilizando las funciones de expansión de parámetros del shell
${parameter%pattern}El 'patrón' se compara con el final del 'parámetro'. El resultado es el valor expandido de 'parámetro' con la coincidencia más corta eliminada.
Entonces, en su caso, reemplace $filePng.txtcon"${filePng%.png}.txt"
Con la variación de lo que Steeldriver ya mencionó (expansión de parámetros), podemos usar el reemplazo de cuerdas para hacer el trabajo. Además, debe citar variables. A continuación se muestra su guión editado.
Si tiene muchos archivos para crear, valdría la pena "tocar" más de un archivo a la vez, de modo que no necesite bifurcar un nuevo proceso para cada uno de ellos (lo que lleva bastante tiempo si se realizan múltiples Mil veces).
Opción 1: sustitución de patrones + xargs
Esta opción proporcionará múltiples rutas al touchcomando a la vez, generalmente unos pocos miles o lo que el sistema pueda caber en una sola línea de comando.
Esto almacena todas las rutas a los archivos que terminan en .pnguna matriz y luego usa la expansión de parámetros para crear la lista de .txtarchivos, sustituyéndola .pngpor .txtcada uno.
Tenga en cuenta que esto se romperá si tiene tantos archivos que no se pueden pasar todos como argumentos a la misma invocación de touch.
for filePng in "$folder"/*
ytouch "$filePng".txt
, tenga en cuenta que solo los cita cuando está precedido por a$
.Respuestas:
Puedes usar el
basename
comando aquí:Tenga en cuenta el adicional
$folder/
. Esto es necesario ya que el comando basename elimina la ruta de.fuente
$filePng
, también fueron útiles.$( )
establece un nuevo contexto de citas.Puede eliminar la extensión existente utilizando las funciones de expansión de parámetros del shell
Entonces, en su caso, reemplace
$filePng.txt
con"${filePng%.png}.txt"
fuente
Con la variación de lo que Steeldriver ya mencionó (expansión de parámetros), podemos usar el reemplazo de cuerdas para hacer el trabajo. Además, debe citar variables. A continuación se muestra su guión editado.
fuente
Si tiene muchos archivos para crear, valdría la pena "tocar" más de un archivo a la vez, de modo que no necesite bifurcar un nuevo proceso para cada uno de ellos (lo que lleva bastante tiempo si se realizan múltiples Mil veces).
Opción 1: sustitución de patrones +
xargs
Esta opción proporcionará múltiples rutas al
touch
comando a la vez, generalmente unos pocos miles o lo que el sistema pueda caber en una sola línea de comando.Opción 2: expansión de parámetros + redirección de salida de comando
Esta opción no se ejecuta
touch
en absoluto, sino que utiliza características de shell Bash / Bourne / POSIX que no requieren subprocesos en absoluto.fuente
Si está seguro de que no tiene archivos en
.png
algún lugar en el medio del nombre, puede usar una matriz con expansión de parámetros:Esto almacena todas las rutas a los archivos que terminan en
.png
una matriz y luego usa la expansión de parámetros para crear la lista de.txt
archivos, sustituyéndola.png
por.txt
cada uno.Tenga en cuenta que esto se romperá si tiene tantos archivos que no se pueden pasar todos como argumentos a la misma invocación de
touch
.fuente