Usando la expansión de parámetros para generar la lista de argumentos para `mkdir -p`


10

Tengo algo como esto:

% ls -1dF /tmp/foo/*
/tmp/foo/000f9e956feab3ee4625aebb65ae7bae9533cdbc/
/tmp/foo/002e34c2218f2c86fefd2876f0e5c2559c5fb3c4/
/tmp/foo/00b483576791bab751e6cb7ee0a7143af43a8069/
.
.
.
/tmp/foo/fedd0f7b545e7ae9600142656756456bc16874d3/
/tmp/foo/ff51ac87609012137cfcb02f36624f81cdc10788/
/tmp/foo/ff8b983a7411395344cad64182cb17e7cdefa55e/

Quiero crear un directorio bardebajo de cada uno de los subdirectorios debajo foo.

Si trato de hacer esto con

% mkdir -p /tmp/foo/*/bar

... me sale el error

zsh: no matches found: /tmp/foo/*/bar

(En retrospectiva, puedo entender la razón del error).

Sé que puedo resolver el problema original con un bucle for, pero tengo curiosidad por saber si zshadmite alguna forma de expansión de parámetros que produzca el argumento deseado para una sola invocación de mkdir -p. IOW, una expansión de parámetro equivalente a "agregar /bara cada prefijo generado al expandir /tmp/foo/*", lo que resulta en

% mkdir -p /tmp/foo/000f9e956feab3ee4625aebb65ae7bae9533cdbc/bar ... /tmp/foo/ff8b983a7411395344cad64182cb17e7cdefa55e/bar

Respuestas:


13
setopt histsubstpattern extendedglob
mkdir -p /tmp/foo/*(#q/:s_%_/bar_)

Este es un globing extendido que tiene un qindicador de glob uiet que usa un calificador glob para hacer coincidir solo directorios y un modificador para realizar una ssustitución (usando el %carácter de patrón que solo está disponible en el modo de patrón de sustitución del historial ) que agrega una cadena a cada palabra.

man zshexpn

Wow estoy impresionado. Incluso lo encontré todo en la página de manual que especifique.
Comodín el

1
Tenga en cuenta que el póster original especificado mkdir -p, que tendría un efecto ligeramente diferente de su comando de no arrojar errores si algunos de esos directorios ya tienen barsubdirectorios. Punto menor pero vale la pena señalar aquí. :)
Comodín el

1
Otra forma es usar la expansión de matriz a través de ${^spec}y agregar bara cada elemento de lo que se /tmp/foo/*(/)expande a: set -- /tmp/foo/*(/)luegomkdir -p -- "${^@}/bar"
don_crissti

5

Claro, usa un bucle

for n in /tmp/foo/*; do mkdir "$n/bar";done

los globos se utilizan para expandir listas de elementos existentes , no cosas que aún no se han creado.


Lo siento, me temo que mi pregunta no fue formulada claramente. Lo aclararé.
kjo

2
Esto no responde si zshpuede expandir los globos y agregar texto con una sintaxis única, pero creo que es la única forma de hacer lo que quiere, @kjo.
Comodín el

4

Si los directorios están en una matriz, puede usar la ${^...}forma de expansión.

a=(/tmp/foo/*/)
mkdir -p ${^a}bar

0

Puedes usar findy xargspara hacerlo:

find /tmp/foo -maxdepth 1 -mindepth 1 -type d | xargs -i echo mkdir -p {}/bar

que utiliza -maxdepth 1y -mindepth 1para evitar la creación baren subdirectorios de objetivos, y en /tmp/foosí mismo respectivamente. type dlo hace considerar solo directorios.

Debe eliminar echopara realizar acciones reales, de lo contrario echosolo imprimirá líneas para ejecutar. También puede encerrarlo en sustitución $()para ejecutarlo.

Manual dice que xargs -ies obsoleto, pero no he encontrado ninguna otra alternativa igualmente útil, por lo que debe todavía trabajo por algunos años ... Se puede reemplazar -icon -I'{}'a estar al día con eso.


Esta respuesta y la siguiente me parecen bien. ¿Alguien puede explicar por qué deberían ser rechazados? Los votos negativos están bien, pero ¿cómo podemos saber si no se dan razones?
Joe

Es una alternativa de trabajo que no hace más que lo que OP pidió. Me gana
loa_in_

Creo que es una especie de sesgo que las respuestas deben tener malas respuestas, por lo que los prejuicios afectaron mi reputación.
loa_in_

No me gustan los votos negativos inexplicables, pero no he visto tal sesgo. Por lo general, las respuestas "malas" (las que entiendo) son realmente malas.
Joe

0

@loa_in_ tenía la mayor parte, pero la findsalida de la tubería tiende a ser un paso en falso.

find /tmp/foo -maxdepth 1 -mindepth 1 -type d -exec mkdir {}/bar \;

Solo lo uso xargscon diferentes herramientas que no tienen -execalternativa, así que uso mi enfoque, ya que funciona con todas ellas por igual.
loa_in_
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.