ubuntuusers.de

Bash / Shell neueste Datei nach Schema finden

Status: Gelöst | Ubuntu-Version: Server 18.04 (Bionic Beaver)
Antworten |

pascalts

Avatar von pascalts

Anmeldungsdatum:
6. Mai 2013

Beiträge: 89

Moin!

Ich versuche mittels eines Bash Scriptes die aktuellste Datei in einem Ordner mit einem STRING im Dateinamen zu finden.

Beispiel im Ordner sind die Dateien

1111_STRING_12323534534534.jpeg
2222_STRING_10984761098426.png
3333_STRING_10984762292324.jpeg
4444_STRING_10984761456456.png
[und andere]

Wobei alle gemeinsam das Suchwort STRING haben. Nun möchte ich die neueste, sprich zuletzt modifizierte Datei herausfinden, die STRING enthält und die Endung jpeg hat.

Mit

1
find -mindepth 1 -maxdepth 1 -type f | grep -i ".jpeg" | grep -i "STRING"

Finde ich schon mal alle Dateien die mit .jpeg enden und STRING im Dateiname haben. Aber davon gibt es eben mehrere und ich möchte die aktuellste haben.

Jemand einen Vorschlag?

Danke!

Bearbeitet von rklm:

Codeblock

sebix Team-Icon

Ehemalige

Anmeldungsdatum:
14. April 2009

Beiträge: 5582

Ungetestet:

find -mindepth 1 -maxdepth 1 -type f -iname "*STRING*.jpeg" -print0 | xargs -0 ls -1t | head -n 1

EDIT: Das geht natuerlich nur so lange gut, wie die Laenge aller Dateinamen von find nicht das erlaubte Maximum fuer command line parameter sprengt. Falls das der Fall ist, kann man dahinter einfach nochmal xargs und head wiederholen.

frostschutz

Avatar von frostschutz

Anmeldungsdatum:
18. November 2010

Beiträge: 7790

Du kannst find auch den Timestamp mit ausgeben lassen und danach sortieren.

Und in find selbst die Ausgabe filtern (zu alte Dateien nicht ausgeben lassen). Dazu könntest du dir den jeweils letzten Timestamp merken und dann im weiteren Verlauf nur noch neuere Dateien in Betracht ziehen.

Was ist das für eine lustige Zahl in den Dateinamen, ist die zufällig oder gibt diese auch das Dateialter - unabhängig vom Timestamp - an? Dann lieber das als Kriterium nehmen...

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13210

1
2
3
d=0
for f in ~/bin/*STRING*.jpeg; do i=$(stat -c %Y "$f"); if [ $i -ge $d ]; then d=$i; file=$f; fi; done
echo "$file"

sebix schrieb:

Ungetestet:

find -mindepth 1 -maxdepth 1 -type f -iname "*STRING*.jpeg" -print0 | xargs -0 ls -1t | head -n 1

Oh, nicht die Ausgabe von ls parsen. Dann lieber

1
find -mindepth 1 -maxdepth 1 -type f -iname "*STRING*.jpeg" -exec stat -c '%Y %n' {} + | sort -nr | sed -n '1{s#^[0-9]* ##p;q}'

schragge

Anmeldungsdatum:
27. Januar 2022

Beiträge: 181

-exec stat -c '%Y %n' {} + kann durch -printf '%Ts %p\n' ersetzt werden.

Und wenn man auf die Nummer sicher gehen will

find -maxdepth 1 -type f -iname '*STRING*.jpeg' -printf '%Ts %p\0'|sort -nrz|sed -z '1{s/^[^ ]* //;q}'|tr \\0 \\n 

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17621

Wohnort: Berlin

Eine Frage wäre noch, was bei 2 Dateien passieren soll, die exakt gleich alt sind.

Sollen dann alle jüngsten Dateien ausgegeben werden, eine beliebige oder eine Datei nach einem anderen Kriterium?

1
ls "*STRING*.jpeg" -1 --sort=time | head -n1

Das findet zwar auch Verzeichnisse, die dem Namensmuster entsprechen, aber das ist wahrscheinlich in der Praxis irrelevant, ebenso wie die Möglichkeit, dass der Dateiname einen Zeilenumbruch enthält und damit "head -n1" austrickst - eine wohl eher theoretische Gefahr.

pascalts

(Themenstarter)
Avatar von pascalts

Anmeldungsdatum:
6. Mai 2013

Beiträge: 89

Erst einmal danke für alle Anworten.

Auf die Idee direkt in find meine "Suchkirterien" einzugeben bin ich gar nicht gekommen.

@frostschutz: Das Zahlenwirrwar war nur zu Demonstraktionszwecken, dass da irgendwas alphanumerisches stehen kann.

@user_unknown: Bei den in meinem Fall eher theoretischen Problem zweier gleichen Datein wäre es egal, welche genommen würde. Ordner sollen nicht gefunden werden.

Ich danke für die Tipps uns schaue mal, was am besten für mich passt, dann melde ich mich am Wochenende nochmal.

DANKE!

pascalts

(Themenstarter)
Avatar von pascalts

Anmeldungsdatum:
6. Mai 2013

Beiträge: 89

schragge schrieb:

-exec stat -c '%Y %n' {} + kann durch -printf '%Ts %p\n' ersetzt werden.

Und wenn man auf die Nummer sicher gehen will

find -maxdepth 1 -type f -iname '*STRING*.jpeg' -printf '%Ts %p\0'|sort -nrz|sed -z '1{s/^[^ ]* //;q}'|tr \\0 \\n 

Diese Lösung funktioniert am besten für mich. Nochmals danke!

Antworten |