Usando a expansão de parâmetro para gerar lista de argumentos para 'mkdir -p'

10

Eu tenho algo assim:

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

Eu quero criar um diretório bar em cada subdiretório em foo .

Se eu tentar fazer isso com

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

... recebo o erro

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

(Em retrospecto, eu posso entender o motivo do erro.)

Eu sei que posso resolver o problema original com um loop, mas estou curioso para saber se zsh suporta alguma forma de expansão de parâmetro que produziria o argumento desejado para uma única invocação de mkdir -p . IOW, uma expansão de parâmetro equivalente a "acrescentar /bar a cada prefixo gerado pela expansão de /tmp/foo/* ", resultando em

% mkdir -p /tmp/foo/000f9e956feab3ee4625aebb65ae7bae9533cdbc/bar ... /tmp/foo/ff8b983a7411395344cad64182cb17e7cdefa55e/bar
    
por kjo 11.10.2016 / 10:31

5 respostas

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

Isso é globbing estendido que tem um% glob glob flag que usa um glob qualifier para corresponder somente aos diretórios e a > modificador para executar uma q ubstitution (usando o caractere s padrão que está disponível apenas no modo padrão de substituição do histórico ) que acrescenta uma string a cada palavra.

man zshexpn
    
por 11.10.2016 / 11:56
5

Claro - use um loop

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

globs são usados para expandir listas de itens existentes , não coisas que ainda não foram criadas.

    
por 11.10.2016 / 10:33
4

Se os diretórios estiverem em uma matriz, você poderá usar a forma de expansão ${^...} .

a=(/tmp/foo/*/)
mkdir -p ${^a}bar
    
por 11.10.2016 / 16:10
0

Você pode usar find e xargs para fazer isso:

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

que usa -maxdepth 1 e -mindepth 1 para impedir a criação de bar em subdiretórios de destinos e em /tmp/foo , respectivamente. type d faz com que ele considere somente diretórios.

Você precisa remover echo para realizar ações reais, caso contrário, echo somente imprimirá as linhas a serem executadas. Você também pode colocá-lo em substituição como $() para executá-lo.

O manual diz que xargs -i está obsoleto, mas não encontrei outra alternativa igualmente útil, por isso ainda deve funcionar por alguns anos ... Você pode substituir -i por -I'{}' para estar atualizado com isso.

    
por 11.10.2016 / 19:29
0

@loa_in_ tinha a maior parte, mas o fluxo da saída find tende a ser um engano.

find /tmp/foo -maxdepth 1 -mindepth 1 -type d -exec mkdir {}/bar \;
    
por 12.10.2016 / 02:59

Tags