mkdir -p
creerà una directory; creerà anche le directory principali secondo necessità.
Esiste un comando simile per i file, che creerà un file e le directory principali secondo necessità?
mkdir -p
creerà una directory; creerà anche le directory principali secondo necessità.
Esiste un comando simile per i file, che creerà un file e le directory principali secondo necessità?
Risposte:
L'installazione eseguirà questa operazione, se fornito il file di origine /dev/null
. L' -D
argomento dice di creare tutte le directory principali:
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
Non sono sicuro che si tratti di un bug o meno: il suo comportamento con i file del dispositivo non è menzionato nella manpage. Potresti anche dargli un file vuoto (appena creato con mktemp
, ad esempio) come sorgente.
Mi sono imbattuto spesso in questo tipo di situazione, quindi ho semplicemente scritto una funzione nel mio .bashrc
file. Sembra così
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
}
Quindi, quando voglio creare un file all'interno di un percorso di directory inesistenti, lo dirò
create what/is/it # will create dirs 'what' and 'is', with file 'it' inside 'is'
touchp
, tipomkdir -p
Stavo per suggerire che la mantiene su una riga, sebbene l'impostazione della variabile separatamente ti permetta di cambiarla e rieseguire il comando dalla cronologia abbastanza facilmente.
B="./make/this/path" && mkdir -p -- "$B" && touch -- "$B/file.txt"
È possibile "fingere".
Rob Griffiths ha pubblicato un articolo nel 2007 intitolato Creare facilmente molte nuove cartelle su Macworld.com in cui ha discusso usando il xargs
comando per leggere un elenco di file per creare directory usandomkdir
.
xargs
è in grado di fare riferimento a a placeholder
( {}
) con il -I
flag, che contiene il valore per ogni argomento passato a xargs
. Ecco la differenza tra con quella bandiera e senza:
$ foo.txt bar.txt | xargs echo
$ => foo.txt bar.txt
$ foo.txt bar.txt | xargs -I {} echo {}
$ => foo.txt
$ => bar.txt
xargs
è anche in grado di eseguire comandi di shell arbitrari con il sh -c
flag:
foo.txt bar.txt | xargs sh -c 'echo arbitrary command!'
Siamo in grado di combinare questi concetti con mkdir -p
al posto del mkdir
e il concetto in @ldx 's risposta per produrre questo:
$ cat files.txt | xargs -I {} sh -c 'f="{}" && mkdir -p -- "${f%/*}" && touch -- "$f"'
Questo comando fondamentalmente mappa ogni nome di file in un elenco di file separato da linee, taglia la parte del file, crea le directory con mkdir -p
e poitouch
es il nome del file nella rispettiva directory.
Di 'ad esempio il mio files.txt
aspetto simile al seguente:
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
viene convogliato a xargs
-I {}
, xargs
traduciamo ogni argomento nel suo comando, quindi ora abbiamo:
deeply/nested/foo/bar.txt
deeply/nested/baz/fiz.txt
&&
combinatore per raggruppare 3 comandi eseguiti in sequenza: il primo comando memorizza il file in una variabile di ambiente (che viene riutilizzato al successivo passaggio di file) utilizzando il segnaposto che abbiamo registrato in precedenza, quindi ora avere:
f=deeply/nested/foo/bar.txt
f=deeply/nested/baz/fiz.txt
mkdir -p
, ma dobbiamo tagliare il nome del file. Abbastanza semplice usando '${f%/*}'
:
mkdir -p deeply/nested/foo/
mkdir -p deeply/nested/baz/
f
variabile nella sua interezza 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"'
, che ha UUOC, quindi ti sottrai a xargs che ricadono nella shell, quando un while read
ciclo ha più senso
while read f; do mkdir -p "$(dirname "$f")"; touch "$f"; done < files.txt
. Anche il fatto che non si possa fare una ricerca su Internet di 10 secondi per UUOC lo dice