Nicht, dass mir das bewusst wäre ... aber Sie könnten einfach mkdir -p / path / to / make && touch / path / to / file ... ausführen. Dadurch würde eine leere Datei in der neuen Verzeichnisstruktur erstellt, die Sie bei Bedarf erstellt haben.
1
@Kansha kombiniert das mit dirnameund basenameund wir brauchen nur das einzige Argument; profitieren! :)
Ja, guten Ruf.
Antworten:
29
Install wird dies tun, wenn die Quelldatei angegeben wird /dev/null. Das -DArgument besagt, dass alle übergeordneten Verzeichnisse erstellt werden sollen:
anthony@Zia:~$ install -D /dev/null /tmp/a/b/c
anthony@Zia:~$ ls -l /tmp/a/b/c
-rwxr-xr-x 1 anthony anthony 0Jan3010:31/tmp/a/b/c
Nicht sicher, ob das ein Fehler ist oder nicht - sein Verhalten mit Gerätedateien wird in der Manpage nicht erwähnt. Sie können ihm auch einfach eine leere Datei ( mktempzum Beispiel neu erstellt mit ) als Quelle geben.
Das testwird nicht benötigt; mkdir -ptut nichts, wenn das Verzeichnis bereits existiert. Gibt nicht einmal einen Fehler zurück.
Derobert
1
Dabei wird natürlich nur das Verzeichnis erstellt.
einen Lebenslauf vom
0
Ich wollte vorschlagen, wie es es in einer Zeile hält, obwohl das separate Festlegen der Variablen es Ihnen ermöglicht, es zu ändern und den Befehl aus dem Verlauf ziemlich einfach erneut auszuführen.
Rob Griffiths veröffentlichte 2007 einen Artikel mit dem Titel " Einfach viele neue Ordner erstellen" auf Macworld.com, in dem er die Verwendung des xargsBefehls zum Einlesen einer Liste von Dateien zum Erstellen von Verzeichnissen mit erläuterte mkdir.
xargskann auf ein placeholder( {}) mit dem -IFlag verweisen , das den Wert für jedes Argument enthält, an das übergeben wird xargs. Hier ist der Unterschied zwischen mit dieser Flagge und ohne:
Dieser Befehl ordnet grundsätzlich jeden Dateinamen in einer zeilengetrennten Liste von Dateien zu, schneidet den Dateiteil ab, erstellt die Verzeichnisse mit mkdir -pund es dann touchden Dateinamen in seinem jeweiligen Verzeichnis.
Hier ist eine Aufschlüsselung dessen, was im obigen Befehl passiert:
Sagen Sie zum Beispiel, dass mein files.txtAussehen so ist:
deeply/nested/foo/bar.jsdeeply/nested/baz/fiz.txt wird zu geleitet xargs
da wir verwendet haben -I {}, xargswird jedes Argument in einen eigenen Befehl übersetzt, so dass wir jetzt haben:
deeply/nested/foo/bar.txt
deeply/nested/baz/fiz.txt
Anschließend führen wir einen Shell-Befehl aus, der den &&Kombinator verwendet, um 3 Befehle zu gruppieren, die nacheinander ausgeführt werden. Der erste Befehl speichert die Datei in einer Umgebungsvariablen (die beim nächsten Dateidurchlauf wiederverwendet wird) und verwendet dabei den zuvor registrierten Platzhalter haben:
f=deeply/nested/foo/bar.txt
f=deeply/nested/baz/fiz.txt
Wir haben jetzt eine Variable, an die wir übergeben können mkdir -p, aber wir müssen den Dateinamen ausschneiden. Einfach genug mit '${f%/*}':
mkdir -p deeply/nested/foo/
mkdir -p deeply/nested/baz/
und dann referenzieren wir die fVariable einfach in ihrer Gesamtheit neu, wenn wir touch:
Sie haben all diese Erklärungen für das Wesentliche cat files.txt | xargs -I {} sh -c 'f="{}" && mkdir -p -- "${f%/*}" && touch -- "$f"', was UUOC hat, dann unterteilen Sie in Xargs, die wieder in die Shell unterteilen, wenn eine while readSchleife sinnvoller ist
Steven Penny
1
Ich gebe zu, dass ich keine Ahnung von * nix-Befehlen habe - ich weiß nicht einmal, was UUOC ist -, aber ich verstehe nicht, wie schrecklich diese Antwort ist. Es wurde recherchiert, getestet und ist eine funktionierende Lösung für Ihre ursprüngliche Frage. Es ist konstruktiv (im Gegensatz zu Ihrem eher unhöflichen Kommentar). Bitte, wenn Sie das Gefühl haben, dass ich hier etwas Verantwortungsloses getan habe, das ich nicht hätte tun sollen, dann gehen Sie weiter vor - erklären Sie, warum . Meinungsverschiedene Debatten, die keine Substanz haben, interessieren mich nicht sonderlich.
Razorbeard
1
Mein letzter Kommentar erklärt es perfekt. Ihre gesamte Antwort könnte besser geschrieben werden als while read f; do mkdir -p "$(dirname "$f")"; touch "$f"; done < files.txt. Die Tatsache, dass Sie keine 10-Sekunden-Internetsuche nach UUOC durchführen können, ist ebenfalls bezeichnend
dirname
undbasename
und wir brauchen nur das einzige Argument; profitieren! :)Antworten:
Install wird dies tun, wenn die Quelldatei angegeben wird
/dev/null
. Das-D
Argument besagt, dass alle übergeordneten Verzeichnisse erstellt werden sollen:Nicht sicher, ob das ein Fehler ist oder nicht - sein Verhalten mit Gerätedateien wird in der Manpage nicht erwähnt. Sie können ihm auch einfach eine leere Datei (
mktemp
zum Beispiel neu erstellt mit ) als Quelle geben.quelle
Nein, soweit ich weiß, ist es nicht so. Sie können aber immer
mkdir -p
undtouch
nacheinander verwenden:quelle
Ich bin häufig auf solche Situationen gestoßen, deshalb habe ich einfach eine Funktion in meine
.bashrc
Datei geschrieben. Es sieht aus wie dasWenn ich also eine Datei in einem Pfad nicht vorhandener Verzeichnisse erstellen möchte, werde ich sagen
quelle
touchp
, wiemkdir -p
quelle
test
wird nicht benötigt;mkdir -p
tut nichts, wenn das Verzeichnis bereits existiert. Gibt nicht einmal einen Fehler zurück.Ich wollte vorschlagen, wie es es in einer Zeile hält, obwohl das separate Festlegen der Variablen es Ihnen ermöglicht, es zu ändern und den Befehl aus dem Verlauf ziemlich einfach erneut auszuführen.
quelle
Es ist möglich, es zu "fälschen".
Erstens einige erforderliche Theorie:
Rob Griffiths veröffentlichte 2007 einen Artikel mit dem Titel " Einfach viele neue Ordner erstellen" auf Macworld.com, in dem er die Verwendung des
xargs
Befehls zum Einlesen einer Liste von Dateien zum Erstellen von Verzeichnissen mit erläutertemkdir
.xargs
kann auf einplaceholder
({}
) mit dem-I
Flag verweisen , das den Wert für jedes Argument enthält, an das übergeben wirdxargs
. Hier ist der Unterschied zwischen mit dieser Flagge und ohne:xargs
kann auch beliebige Shell-Befehle mit demsh -c
Flag ausführen :Die Konzepte kombinieren:
Wir können diese Konzepte mit und
mkdir -p
anstelle desmkdir
Konzepts in @ldx 's Antwort kombinieren , um Folgendes zu erzeugen:Dieser Befehl ordnet grundsätzlich jeden Dateinamen in einer zeilengetrennten Liste von Dateien zu, schneidet den Dateiteil ab, erstellt die Verzeichnisse mit
mkdir -p
und es danntouch
den Dateinamen in seinem jeweiligen Verzeichnis.Hier ist eine Aufschlüsselung dessen, was im obigen Befehl passiert:
Sagen Sie zum Beispiel, dass mein
files.txt
Aussehen so ist:cat files.txt
produziertdeeply/nested/foo/bar.js
deeply/nested/baz/fiz.txt
deeply/nested/foo/bar.js
deeply/nested/baz/fiz.txt
wird zu geleitetxargs
-I {}
,xargs
wird jedes Argument in einen eigenen Befehl übersetzt, so dass wir jetzt haben:deeply/nested/foo/bar.txt
deeply/nested/baz/fiz.txt
&&
Kombinator verwendet, um 3 Befehle zu gruppieren, die nacheinander ausgeführt werden. Der erste Befehl speichert die Datei in einer Umgebungsvariablen (die beim nächsten Dateidurchlauf wiederverwendet wird) und verwendet dabei den zuvor registrierten Platzhalter haben:f=deeply/nested/foo/bar.txt
f=deeply/nested/baz/fiz.txt
mkdir -p
, aber wir müssen den Dateinamen ausschneiden. Einfach genug mit'${f%/*}'
:mkdir -p deeply/nested/foo/
mkdir -p deeply/nested/baz/
f
Variable einfach in ihrer Gesamtheit neu, wenn wirtouch
:touch deeply/nested/foo/bar.txt
touch deeply/nested/baz/fiz.txt
quelle
cat files.txt | xargs -I {} sh -c 'f="{}" && mkdir -p -- "${f%/*}" && touch -- "$f"'
, was UUOC hat, dann unterteilen Sie in Xargs, die wieder in die Shell unterteilen, wenn einewhile read
Schleife sinnvoller istwhile read f; do mkdir -p "$(dirname "$f")"; touch "$f"; done < files.txt
. Die Tatsache, dass Sie keine 10-Sekunden-Internetsuche nach UUOC durchführen können, ist ebenfalls bezeichnend