
Ich habe den nächsten Befehl ausgegeben, um einige Verzeichnisse in den Ordner „build_tools“ zu verschieben, das Ergebnis war jedoch nicht das erwartete.
ls -l | grep 2014-03 | awk '{if ($8!=build_tools) print $8}' | xargs mkdir build_tools/{} && mv {}/ build_tools/{}/
Es hat den Ordner „build_tools“ zusammen mit den übrigen Verzeichnissen in einen der von awk bereitgestellten Ordner (zlib) verschoben und blieb dann mit dieser Meldung hängen:
mkdir: no se puede crear el directorio «zlib»: El archivo ya existe
Kann jemand Licht ins Dunkel bringen, was mein Fehler ist?
BEARBEITEN 1:
Die Ausgabe von ls -l gibt mir:
drwxr-xr-x 3 poissonbreaker poissonbreaker 4096 2011-05-02 09:58 antlr3.2
-rw-r--r-- 1 poissonbreaker poissonbreaker 318588 2011-05-17 16:21 AppFramework-1.03.jar
-rw-r--r-- 1 poissonbreaker poissonbreaker 0 2014-03-04 09:53 awk
drwxr-xr-x 4 poissonbreaker poissonbreaker 4096 2013-01-11 23:13 clutter-sharp
-rw-r--r-- 1 poissonbreaker poissonbreaker 429 2014-01-14 09:49 Dependencias
Ich möchte nur die Dateien mit dem Datumsfeld ($6) abrufen, das mit 2014-03 übereinstimmt. Deshalb führe ich ein einfaches Grep davon aus (keine Datei im Verzeichnis hat dieses Muster als Dateinamen):
ls -l | grep 2014-03
Das ergibt:
-rw-r--r-- 1 poissonbreaker poissonbreaker 0 2014-03-04 09:53 awk
-rw-r--r-- 1 poissonbreaker poissonbreaker 429 2014-01-14 09:49 Dependencias
Dann hole ich mir das Dateinamenfeld ($8) jeder Datei über awk, um es schließlich in den Ordner build_tools zu verschieben (An diesem Punkt weiß ich, was mein Fehler war – der Ordner build_tools wurde ebenfalls an diesem Datum erstellt :S). Ich werde diese Frage jedoch hier lassen, falls einige Teile für irgendjemanden nützlich sein sollten.
BEARBEITEN 2: Ich habe den awk-Ausdruck wie folgt geändert:
awk '{if ($8!=build_tools) print $8}'
damit es Sinn ergibt.
Antwort1
Ich gehe davon aus, dass Sie GNU haben find
. Wenn Sie Dateien oder Verzeichnisse verschieben möchten, die innerhalb eines bestimmten Zeitraums (z. B. März 2014) geändert wurden, gehen Sie wie folgt vor:
find . -maxdepth 1 \
-newermt 2014-02-28 -not -newermt 2014-04-01 \
-not -name 'build_tools' \
-exec mv {} build_tools \+
Erläuterung:
- finden Sie in diesem Verzeichnis, ohne Unterverzeichnisse
- Dateien im Zeitraum zwischen dem 28. Februar und dem 1. April, wobei
mt
sich auf den Änderungszeitpunkt bezieht. Sie können auchct
nach dem Erstellungszeitpunkt suchen. - die nicht benannt sind
build_tools
- verschiebe sie alle nach
build_tools
. Das\+
bedeutet, dass alle gefundenen Datei-/Verzeichnisnamen in ersetzt werden{}
, statt einzeln. Wenn Sie einzeln möchten, benötigen Sie\;
stattdessen.
Ein paar Dinge:
Analysieren Sie nicht die Ausgabe von
ls
. Das Format ist vom Betriebssystem abhängig und die Spaltenauswahl schlägtawk
fehl, wenn die Datei-/Verzeichnisnamen Leerzeichen enthalten.Sie haben
&
Befehle verkettet, aber&
nur einen Prozess in den Hintergrund gestellt. Wenn überhaupt, hätten Sie verwenden sollen&&
, aber alles in allem wäre es ziemlich kompliziert, das zu erreichen, was Sie wollen.
Antwort2
Die richtige Version für meine Lösung benötigt xargs, um mehrere Befehle zu verarbeiten. Dies kann erreicht werden, indem die Befehle wie folgt umschlossen werden:
sh -c (or bash -c) 'Command1; Command2; .. Comandn'
Die richtige Lösung ist also:
ls -l awk ' $8!=build_tools && $6 ~ /2013-03*/ {print $8}' | xargs -I @ sh -c 'mkdir build_tools/@; mv @ build_tools/@'
Beachten Sie, dass dadurch für jede zu verschiebende Datei ein neuer Ordner erstellt wird.
Unterm Strich lässt sich sagen, dass wir, obwohl andere uns mit besseren und spezialisierteren Tools das Leben leichter machen, immer noch viel von Piped-Abfragen im alten Stil lernen können. Zumindest in meinem Fall :)