O ponto que você pode estar perdendo - com o qual muitas pessoas têm problemas, especialmente se tiverem experiência com outros sistemas operacionais antes de chegarem ao * nix - é que, em muitos outros sistemas operacionais, os curingas na linha de comando são normalmente passados ao comando para processar como achar melhor. Por exemplo, no Prompt de Comando do Windows,
rename *.jpeg *.jpg
Considerando que, em * nix, a fim de simplificar o trabalho
do (s) programador (es) dos comandos individuais (por exemplo, mv
), curingas
(quando não citado ou escapado) são manipulados pelo shell,
de uma maneira independente da interface e da funcionalidade
do comando para o qual os caracteres curinga são argumentos.
A maioria dos programas que usam nomes de arquivos como argumentos de linha de comando espera que esses arquivos existam
(sim, mkdir
e touch
são exceções a essa regra,
como são mkfifo
, mknod
e, em parte, cp
, ln
, mv
e rename
;
e provavelmente há outros)
por isso não faz sentido para o shell expandir curingas
para nomes de arquivos que não existem.
E para o shell (e, por isso, eu quero dizer todo shell -
Bourne, bash, csh, fish, ksh, zsh, etc ...) para lidar com as exceções de forma diferente
provavelmente seria muito trabalhoso.
Dito isso, há algumas maneiras de obter um resultado como o que você deseja. Se você sabe para o que o curinga vai se expandir, e não é muito tempo, você pode gerá-lo com a expansão de chaves:
touch {red,orange,yellow,green,blue,indigo,violet}/rgb.txt
Uma solução mais geral:
sh -c 'for arg do mkdir -- "$arg"/test; done' -- *
Gilles ajudou-me a encontrar outro caminho para fazer isso no bash.
benbradley=(*)
mkdir "${benbradley[@]/%//test}"
Obviamente, benbradley
é apenas um identificador aqui; você pode usar qualquer nome
(por exemplo, qualquer letra única).
Levei algumas tentativas para acertar, então deixe-me explicar:
-
%código%
cria uma variável (escalar) chamada
identifier=value
(se ainda não existir) e atribui o valoridentifier
a ele. Por exemplo,value
. Você pode referenciar uma variável escalar comG=Man
; por exemplo,$identifier
ou, com mais segurança, como$G
. Por exemplo,${identifier}
e$Gage
podem ser indefinidos, mas$Gilla
é${G}age
eManage
é${G}illa
. -
Manilla
cria uma variável de matriz chamadaidentifier=(value1 value2 … )
(se ainda não existir) e atribui os valores listados a ele. Por exemplo,
spectrum=(red orange yellow green blue indigo violet)ou
all_text_files=(*.txt)
identifier
fará referência ao primeiro elemento (e, portanto, é bastante inútil).
Você pode referenciar um elemento arbitrário como $name
;
por exemplo, ${name[subscript]}
é ${spectrum[0]}
e red
é ${spectrum[4]}
.
E você pode usar blue
e ${name[@]}
para referenciar toda a matriz.
Então, aqui está em pedaços:
" ${ benbradley[@] / % / /test } "
-
%código%
expande
${name[*]}
e substitui a correspondência mais longa de${parameter/pattern/string}
com${parameter}
. - Se
pattern
começar comstring
, ele deve corresponder no início do valor expandido depattern
. Se#
começar comparameter
, ele deve corresponder ao final do valor expandido depattern
. Em outras palavras,
%(the-rest_of_the_pattern)age como
(the-rest_of_the_regex)$(sim, isso parece um pouco para trás). Então, um
%
que é apenas um parameter
é como uma expressão regular que é apenas um pattern
-
ele corresponde ao final da string de entrada (espaço de pesquisa).
- E eu estou usando um
%
de$
. Então, isso substitui o final do parâmetro porstring
(isto é, anexa/test
ao parâmetro). - Outra coisa sobre
%código%
Isso não é intuitivo, pois sempre termina com
/test
. Não é necessário, e não pode terminar com um terceiro/test
. Portanto, um${parameter/pattern/string}
em}
não pode ser interpretado como um delimitador, e, portanto, podemos ter um/
de/
sem precisar escapar dostring
. - Se
string
for uma variável de matriz subscrito com/test
ou/
, a operação de substituição é aplicada a cada membro da matriz, por sua vez. - Quando você faz referência a uma matriz como
parameter
(em vez de@
) e colocar os resultados em aspas duplas, você preserva a integridade dos elementos da matriz (isto é, você preserva espaços e outros caracteres especiais neles) sem combinar os elementos separados em uma palavra longa.