É possível "fingir".
Primeiro, alguma teoria obrigatória:
Rob Griffiths postou um artigo em 2007 intitulado Crie facilmente muitas novas pastas no Macworld.com, onde ele discutiu o uso do comando xargs
para ler em uma lista de arquivos para criar diretórios usando mkdir
.
xargs
é capaz de fazer referência a um placeholder
( {}
) com o sinal -I
,
que contém o valor para cada argumento passado para xargs
. Aqui está a diferença entre esse sinalizador 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 shell arbitrários com o sinalizador sh -c
:
foo.txt bar.txt | xargs sh -c 'echo arbitrary command!'
Combinando os conceitos:
Podemos combinar esses conceitos com mkdir -p
em vez de mkdir
e o conceito em @ldx ' s responda para produzir isto:
$ cat files.txt | xargs -I {} sh -c 'f="{}" && mkdir -p -- "${f%/*}" && touch -- "$f"'
Esse comando basicamente mapeia cada nome de arquivo em uma lista separada por linhas de arquivos, 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.
Veja um resumo do que acontece no comando acima:
Digamos, por exemplo, que meu files.txt
seja 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
- porque usamos
-I {}
, xargs
irá traduzir cada argumento para seu próprio comando, então agora temos:
-
deeply/nested/foo/bar.txt
-
deeply/nested/baz/fiz.txt
- em seguida, executamos um comando shell que usa o
&&
combinator para os comandos do grupo 3 que são executados sequencialmente - 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 we registrado antes, então agora temos:
-
f=deeply/nested/foo/bar.txt
-
f=deeply/nested/baz/fiz.txt
- agora temos uma variável que podemos passar para
mkdir -p
, mas precisamos cortar o nome do arquivo. Simples o suficiente usando '${f%/*}'
:
-
mkdir -p deeply/nested/foo/
-
mkdir -p deeply/nested/baz/
- e, em seguida, apenas re-referenciamos a variável
f
em sua totalidade quando touch
:
-
touch deeply/nested/foo/bar.txt
-
touch deeply/nested/baz/fiz.txt