mkdir -p
criará um diretório; também criará diretórios pai, conforme necessário.
Existe um comando semelhante para arquivos, que criará um arquivo e diretórios pai, conforme necessário?
mkdir -p
criará um diretório; também criará diretórios pai, conforme necessário.
Existe um comando semelhante para arquivos, que criará um arquivo e diretórios pai, conforme necessário?
Respostas:
A instalação fará isso, se for fornecido o arquivo de origem /dev/null
. O -D
argumento diz para criar todos os diretórios pai:
anthony@Zia:~$ install -D /dev/null /tmp/a/b/c
anthony@Zia:~$ ls -l /tmp/a/b/c
-rwxr-xr-x 1 anthony anthony 0 Jan 30 10:31 /tmp/a/b/c
Não tenho certeza se isso é um bug ou não - seu comportamento com os arquivos do dispositivo não é mencionado na página de manual. Você também pode fornecer um arquivo em branco (recém-criado mktemp
, por exemplo) como fonte.
Frequentemente me deparei com esse tipo de situação, então simplesmente escrevi uma função no meu .bashrc
arquivo. Se parece com isso
function create() {
arg=$1
num_of_dirs=$(grep -o "/" <<< $arg | wc -l)
make_dirs=$(echo $arg | cut -d / -f1-$num_of_dirs)
mkdir -p $make_dirs && touch $arg
}
Então, quando eu quiser criar um arquivo dentro de um caminho de diretórios inexistentes, direi
create what/is/it # will create dirs 'what' and 'is', with file 'it' inside 'is'
touchp
, tipomkdir -p
dir=$(dirname "$f")
test -d $dir || mkdir -p "$dir"
test
não é necessário; mkdir -p
não faz nada se o dir já existe. Nem retorna um erro.
Eu sugeriria, pois a mantém em uma linha, embora definir a variável separadamente permita alterá-la e executar novamente o comando do histórico com bastante facilidade.
B="./make/this/path" && mkdir -p -- "$B" && touch -- "$B/file.txt"
É possível "fingir".
Rob Griffiths publicou um artigo em 2007 intitulado Crie facilmente muitas novas pastas no Macworld.com, no qual ele discutiu o uso do xargs
comando para ler uma lista de arquivos para criar diretórios usando mkdir
.
xargs
é capaz de referenciar a placeholder
( {}
) com o -I
sinalizador, que contém o valor de cada argumento passado para xargs
. Aqui está a diferença entre com essa bandeira e sem:
$ foo.txt bar.txt | xargs echo
$ => foo.txt bar.txt
$ foo.txt bar.txt | xargs -I {} echo {}
$ => foo.txt
$ => bar.txt
xargs
também é capaz de executar comandos arbitrários do shell com o sh -c
sinalizador:
foo.txt bar.txt | xargs sh -c 'echo arbitrary command!'
Podemos combinar estes conceitos com mkdir -p
, em vez de mkdir
e o conceito em @ldx 's resposta para produzir este:
$ cat files.txt | xargs -I {} sh -c 'f="{}" && mkdir -p -- "${f%/*}" && touch -- "$f"'
Esse comando basicamente mapeia cada nome de arquivo em uma lista de arquivos separados por linha, corta a parte do arquivo, cria os diretórios com mkdir -p
e, em seguida, touch
es o nome do arquivo em seu respectivo diretório.
Digamos, por exemplo, minha files.txt
aparência assim:
deeply/nested/foo/bar.txt
deeply/nested/baz/fiz.txt
cat files.txt
produz deeply/nested/foo/bar.js
deeply/nested/baz/fiz.txt
deeply/nested/foo/bar.js
deeply/nested/baz/fiz.txt
é canalizado para xargs
-I {}
, xargs
traduziremos cada argumento para seu próprio comando, então agora temos:
deeply/nested/foo/bar.txt
deeply/nested/baz/fiz.txt
&&
combinador para agrupar 3 comandos que são executados seqüencialmente - o primeiro comando armazena o arquivo em uma variável de ambiente (que é reutilizada na próxima passagem de arquivo) usando o espaço reservado que registramos antes, então agora ter:
f=deeply/nested/foo/bar.txt
f=deeply/nested/baz/fiz.txt
mkdir -p
, mas precisamos cortar o nome do arquivo. Simples o suficiente usando '${f%/*}'
:
mkdir -p deeply/nested/foo/
mkdir -p deeply/nested/baz/
f
variável na sua totalidade quando touch
:
touch deeply/nested/foo/bar.txt
touch deeply/nested/baz/fiz.txt
cat files.txt | xargs -I {} sh -c 'f="{}" && mkdir -p -- "${f%/*}" && touch -- "$f"'
, que tem UUOC, então você subnível para xargs que subshells volta para o shell, quando um while read
ciclo faz mais sentido
while read f; do mkdir -p "$(dirname "$f")"; touch "$f"; done < files.txt
. O fato de que você não pode fazer uma pesquisa 10 segundo internet para UUOC também está dizendo