mkdir -p
creará un directorio; también creará directorios principales según sea necesario.
¿Existe un comando similar para los archivos, que creará un archivo y directorios principales según sea necesario?
mkdir -p
creará un directorio; también creará directorios principales según sea necesario.
¿Existe un comando similar para los archivos, que creará un archivo y directorios principales según sea necesario?
Respuestas:
Instalar hará esto, si se le da el archivo fuente /dev/null
. El -D
argumento dice crear todos los directorios principales:
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
No estoy seguro de si eso es un error o no: su comportamiento con los archivos del dispositivo no se menciona en la página del manual. También podría simplemente darle un archivo en blanco (recién creado con mktemp
, por ejemplo) como fuente.
Frecuentemente me encontré con este tipo de situación, así que simplemente escribí una función en mi .bashrc
archivo. Se parece a esto
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
}
Entonces, cuando quiera crear un archivo dentro de una ruta de directorios inexistentes, diré
create what/is/it # will create dirs 'what' and 'is', with file 'it' inside 'is'
touchp
, comomkdir -p
Iba a sugerir, ya que lo mantiene en una línea, aunque establecer la variable por separado le permite cambiarlo y volver a ejecutar el comando desde el historial con bastante facilidad.
B="./make/this/path" && mkdir -p -- "$B" && touch -- "$B/file.txt"
Es posible "fingirlo".
Rob Griffiths publicó un artículo en 2007 titulado Easy Create Lots of New Folders en Macworld.com en el que discutió el uso del xargs
comando para leer en una lista de archivos para crear directorios usando mkdir
.
xargs
es capaz de hacer referencia a a placeholder
( {}
) con la -I
bandera, que contiene el valor de cada argumento pasado xargs
. Aquí está la diferencia entre con esa bandera y sin ella:
$ foo.txt bar.txt | xargs echo
$ => foo.txt bar.txt
$ foo.txt bar.txt | xargs -I {} echo {}
$ => foo.txt
$ => bar.txt
xargs
También es capaz de ejecutar comandos de shell arbitrarios con la sh -c
bandera:
foo.txt bar.txt | xargs sh -c 'echo arbitrary command!'
Podemos combinar estos conceptos en mkdir -p
lugar de mkdir
y el concepto en la respuesta de @ldx para producir esto:
$ cat files.txt | xargs -I {} sh -c 'f="{}" && mkdir -p -- "${f%/*}" && touch -- "$f"'
Este comando básicamente asigna cada nombre de archivo en una lista de archivos separados por líneas, corta la parte del archivo, crea los directorios con mkdir -p
y luego touch
es el nombre de archivo en su directorio respectivo.
Digamos, por ejemplo, mi files.txt
aspecto así:
deeply/nested/foo/bar.txt
deeply/nested/baz/fiz.txt
cat files.txt
produce deeply/nested/foo/bar.js
deeply/nested/baz/fiz.txt
deeply/nested/foo/bar.js
deeply/nested/baz/fiz.txt
se canaliza a xargs
-I {}
, xargs
traducirá cada argumento a su propio comando, por lo que ahora tenemos:
deeply/nested/foo/bar.txt
deeply/nested/baz/fiz.txt
&&
combinador para agrupar 3 comandos que se ejecutan secuencialmente: el primer comando almacena el archivo en una variable de entorno (que se reutiliza en el siguiente paso del archivo) usando el marcador de posición que registramos antes, así que ahora tener:
f=deeply/nested/foo/bar.txt
f=deeply/nested/baz/fiz.txt
mkdir -p
, pero necesitamos recortar el nombre del archivo. Bastante simple usando '${f%/*}'
:
mkdir -p deeply/nested/foo/
mkdir -p deeply/nested/baz/
f
variable en su totalidad cuando 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 tiene UUOC, luego se despliega en xargs que se vuelven a colocar en el shell, cuando un while read
bucle tiene más sentido
while read f; do mkdir -p "$(dirname "$f")"; touch "$f"; done < files.txt
. El hecho de que no pueda hacer una búsqueda en Internet de 10 segundos para UUOC también es revelador