Os espaços em um nome de arquivo / diretório são bons, desde que esses nomes sejam citados corretamente:
find . -maxdepth 1 -name "*.doc" | while IFS= read -r f; do
mkdir -- "${f%.doc}";
done
Eu tenho um diretório com uma lista de arquivos nele. Todos esses arquivos têm espaços em seus nomes.
Eu gostaria de criar um diretório, para cada arquivo, com o nome do arquivo, exceto a extensão (que é .doc para todos eles).
Por exemplo:
Meu conteúdo de diretório
first file.doc
second file.doc
third file.doc
Resultado esperado
first file/first file.doc
second file/second file.doc
third file/third file.doc
Eu tenho este comando para saber o nome do diretório que tenho que criar:
find . -maxdepth 1 -name "*.doc" | awk -F ".doc" '{print $1}'
Com isso, o resultado é:
first file
second file
third file
Eu sei que preciso criar um diretório por entrada.
Eu tentei o seguinte sem sucesso:
find . -maxdepth 1 -name "*.doc" | awk -F ".doc" '{print $1}' -exec mkdir '{}' \;
#error with awk: it cannot open the file -exec because it does not exist
mkdir 'find . -maxdepth 1 -name "*.doc" | awk -F ".doc" '{print $1}''
#it creates several directories per name because there are spaces in the names
mkdir '"find . -maxdepth 1 -name "*.doc" | awk -F ".doc" '{print $1}'"'
#-bash: find . -maxdepth 1 -name *.doc | awk -F .doc '{print }': command not found
mkdir "'find . -maxdepth 1 -name "*.doc" | awk -F ".doc" '{print $1}''"
#it tries to create a unique directory with all the file names as a single name, which is not good of course
Se eu pudesse, apenas removeria todos os espaços nos nomes dos arquivos, mas preciso mantê-los para restrições de projeto: /
Quando eu puder criar esses diretórios, terei que descobrir como mover todos os arquivos em seus diretórios correspondentes. Tudo isso pode ser feito em um único comando, eu aceito:)
Estou usando o bash e o RedHat 2.6.
Obrigado pela sua ajuda. Laurent
com zsh
:
mkdir -p -- *.doc(:r)
Ou:
for f (*.doc) {
mkdir -p -- $f:r &&
mv -- $f $f:r/
}
O bash
equivalente (embora também funcione em todos os shells do POSIX e zsh
):
for f in *.doc; do
mkdir -p -- "${f%.*}" &&
mv -- "$f" "${f%.*}/"
done
(observe que ele exclui arquivos ocultos).
cd /path/to/dir
( set -- *\ *
printf 'd="%s" ; mkdir ./"${d%%.doc}"\n' "$@"
) | . /dev/stdin
Você pode definir os parâmetros de um subshell com globs de shell e depois alimentar um pipe com printf e. fonte o pipe como um script.
E se você quiser mover os arquivos em cada diretório:
cd /path/to/dir
( set -- *\ *
printf 'f="%s" ; d="${f%%.doc}"
mkdir ./"$d" ; echo "mv ./\"$f\" ./\"$d\"/\"$f\""\n' "$@"
) | . /dev/stdin
Nota: Eu intencionalmente limpei o acima com eco porque eu quero que você teste a saída antes de mergulhar.
CORRIGIDO - Esqueci de usar duas% porcentagens para printf.
Eu testei isso, a propósito:
% printf 'touch ./"%s file.doc"\n' first second third fourth fifth |
. /dev/stdin
% ls
> fifth file.doc first file.doc fourth file.doc second file.doc third file.doc
% ( set -- *\ *
printf 'f="%s" ; d="${f%%.doc}"
mkdir ./"$d" ; mv ./"$f" ./"$d"\n' "$@"
) | . /dev/stdin
% ls
> fifth file first file fourth file second file third file
% cd fifth\ file ; ls
> fifth file.doc