Fehler „/usr/bin/stat: Argumentliste zu lang“

Fehler „/usr/bin/stat: Argumentliste zu lang“

Ich muss die Liste der .log/.lstin einem Verzeichnis vorhandenen Dateien abrufen $logfolder, deren Erstellungsdatum in einem bestimmten $yearund$month

stat  --format='%y %n'  $logfolder/* |
  grep "$year-$month-"|
  awk -F' ' '{print $4}'|
  grep 'log$\|lst$' > $archivepath/filesToArchive

Dies funktioniert nicht, wenn ich den Befehl an einen Ordner abfrage, in dem sich zu viele Dateien befinden. Ich erhalte die folgende Fehlermeldung:

-bash: /usr/bin/stat: Argument list too long

Antwort1

Eine lustige Möglichkeit: Wenn Ihr findHandle vorhanden -newerXYist, verwenden Sie es! So erhalten Sie beispielsweise die Dateien aus dem Jahr 1977 und dem Monat Oktober:

find "$logfolder" \( -name '*.log' -o -name '*.lst' \) -newermt "1977-10-01" \! -newermt "1977-10-01 +1 month"

Erledigt!

Da Sie die Variablen bereits haben year, monthist es ganz einfach, Folgendes zu schreiben:

find "$logfolder" \( -name '*.log' -o -name '*.lst' \) -newermt "$year-$month-01" \! -newermt "$year-$month-01 +1 month"

Nur ein findBefehl! Erstaunlich!

Antwort2

Ich würde es so machen:

find "$logfolder" \( -name '*.log' -o -name '*lst' \) -printf "%TB\t%TY\t%p\n" |
     awk '$1==m && $2==y' m="$month" y="$year" | cut -f 3- 

Erläuterung

Indem Sie die beiden Aufrufe in Klammern gruppieren -name, können Sie sie mit dem -oFlag (oder) kombinieren. Dadurch wird findnach Dateien mit .logoder ohne gesucht. Das (eine GNU-Erweiterung) gibt den Änderungsmonat der Datei ( ), dann das Änderungsjahr ( ) und dann den Pfad ( ) aus, mit einem Tabulator ( ) zwischen jedem Feld..lst-printf%TB%TY%p\t

Dabei awkwird einfach überprüft, ob das erste Feld (der Monat) mit $monthund das zweite mit übereinstimmt $year.

Dabei cutwerden die ersten beiden Felder (Monat und Jahr) entfernt und alles ab dem 3. Feld ausgedruckt.

Ich habe das oben genannte getestet, indem ich Dateien erstellt habe, die im Dezember 2012 geändert wurden (und $monthauf „Dezember“ und $yearauf 2012 eingestellt sind):

$ touch -d "December 13 2012" {a,b,c}{.lst,.log}
$ touch c.lst a.log ## c.lst and a.log now have today's modification date.
$ find $logfolder \( -name '*.log' -o -name '*lst' \) -printf "%TB\t%TY\t%p\n" |
  awk '$1==m && $2==y' m="$month" y="$year" | cut -f 3-
./b.log
./c.log
./b.lst
./a.lst

(Beachten Sie, dass davon ausgegangen wird, dass Datei- und Verzeichnisnamen keine Zeilenumbruchzeichen enthalten).

Antwort3

Versuche dies:

find $logfolder -type f -exec stat --format='%y %n' "{}" + |
  grep "$year-$month-"|
  awk -F' ' '{print $4}'|
  grep 'log$\|lst$' > $archivepath/filesToArchive

Antwort4

ls -lh *.log *.lst logfolder | grep year | grep month

verwandte Informationen