O curinga não está em expansão

3

Estou tentando criar um diretório para cada arquivo em um diretório.

mkdir *

retorna Arquivo existe. Então eu tento

mkdir *.d

e cria um diretório chamado "* .d". Como forçar o curinga a se expandir?

    
por Gooberpatrol66 19.06.2018 / 08:35

3 respostas

18

Um curinga sempre se expande para os nomes existentes .

Seu comando mkdir * falha porque os nomes que * expande já existem.

Seu comando mkdir *.d "falha" porque o *.d não corresponde a nenhum nome existente. Portanto, o padrão é deixado não expandido por padrão 1 e um diretório chamado *.d é criado. Você pode remover isso com rmdir '*.d' .

Para criar um diretório para cada arquivo regular no diretório atual, para que os novos diretórios tenham o mesmo nome dos arquivos, mas com um sufixo .d :

for name in ./*; do
    if [ -f "$name" ]; then
        # this is a regular file (or a symlink to one), create directory
        mkdir "$name.d"
    fi
done

ou, para pessoas que gostam de "one-liners",

for n in ./*; do [ -f "$n" ] && mkdir "$n.d"; done

Em bash , você também pode fazer

names=( ./* )
mkdir "${names[@]/%/.d}"

mas isso não faz verificações se as coisas para as quais a glob se expande são arquivos regulares ou qualquer outra coisa.

Os ./ iniciais nos comandos acima são para proteger contra nomes de arquivos que contêm um traço inicial ( - ) em seus nomes de arquivos. O traço e os caracteres seguintes seriam interpretados como opções para mkdir .

1 Alguns shells têm uma opção nullglob shell que faz com que os curingas de shell não correspondidos sejam expandidos para uma string vazia. Em bash , isso é ativado usando shopt -s nullglob .

    
por 19.06.2018 / 08:42
2

*.d expande para os arquivos cujo nome termina em .d .

Com zsh , você poderia fazer:

files=(*)
mkdir -- $^files.d

Ou:

mkdir -- *(e{REPLY+=.d})

Você também pode querer não fazer isso para arquivos que já são diretórios ou links simbólicos para diretórios, adicionando um qualificador ^-/ glob:

files=(*(^-/))
mkdir -- $^files.d

Ou:

mkdir -- *(e{REPLY+=.d}^-/)

(note que zsh não tem essa má característica de outras shells parecidas com Bourne, onde os padrões que não correspondem são passados como estão, portanto mkdir *.d não criaria um diretório *.d se não havia nenhum arquivo correspondente a *.d no diretório atual, ele abortaria o comando com um erro)

    
por 19.06.2018 / 09:12
2

Em vez de for foo in bar; do baz; done solution, proponho:

find . -maxdepth 1 -type f -print0|xargs -0 -I file mkdir file.d

    
por 19.06.2018 / 16:15