Numerische Dateinamen suchen und sortieren

476
hadi k

Ich versuche, Dateien zu finden, die übereinstimmen, time=*und muss sie durch numerische Sortierung anzeigen.
Die Ergebnisdateinamen wären:

first/path/time=001.jpg first/path/time=002.jpg second/path/time=001.jpg ... 

was ich als sehen möchte,

first/path/time=001.jpg second/path/time=001.jpg first/path/time=002.jpg ... 

numerisch nach den 3 Ziffern des Dateinamens sortiert.

Im Moment habe ich es versucht find . -name time=* | rev | sort | rev

was funktioniert für einzelne Ziffern, aber mit Zahlen wie 019 021es funktioniert nicht.

Voller Pfad wäre so etwas wie

path/to/folder1/alpha=0.1_beta=0.2_gamma=1.0/time=001.jpg path/to/folder1/alpha=0.1_beta=0.2_gamma=0.1/time=001.jpg path/to/folder2/alpha=0.1_beta=0.2_gamma=0.1/time=001.jpg . . . 

Ich denke, es wäre am einfachsten, wenn die Dateien nur mit den letzten 7 Zeichen sortiert werden könnten. 001.jpg 010.jpg... unterstützt jedoch leider sortkeine negative Indexierung, um die letzten 6 Zeichen zu erhalten :(

2
(1) Welches Betriebssystem? Sieht aus wie ein Unix, trotzdem solltest du es klarstellen. (2) Zitieren Sie das Muster (oder sonst) (https://superuser.com/q/1217773/432690) ... Kamil Maciorowski vor 6 Jahren 1
Hey, es ist Linux und was meinst du damit, das Muster zu zitieren? hadi k vor 6 Jahren 0
Ich meine genau das, was meine Antwort unter diesem Link sagt (https://superuser.com/q/1217773/432690). Kamil Maciorowski vor 6 Jahren 0
hi danke, aber das war bei mir nicht das problem. Ich habe keine `time = *` Datei im aktuellen Verzeichnis, um dieses Problem zu haben. Aber definitiv etwas Neues zu lernen! Danke noch einmal! Ich werde das für die Zukunft behalten. hadi k vor 6 Jahren 0
@ KamilMaciorowski oh nein. Ich meinte nur `time = 001.jpg`` time = 002.jpg` und so weiter. hadi k vor 6 Jahren 0

3 Antworten auf die Frage

2
Tomasz

Dies sollte tun:

find . -name 'time=*' | sort -t= -k3 

Dies ist jedoch eine sicherere Sortierung gemäß dem Kommentar von Kamil Maciorowski:

perl -C -F= -wnle 'push @a,[$_,split(/\./,$F[-1])]; END {$,="\n"; print map{$$_[0]} sort{$$a[1]<=>$$b[1]} @a}' 

Verwenden Sie es in der Pipeline findstatt sortin der ersten.

Es sei denn, Sie treffen auf "Third / path / a = foo / bar / ...". Kamil Maciorowski vor 6 Jahren 0
@KamilMaciorowski `Ich versuche, Dateien zu finden, die mit time = *` übereinstimmen, sagt die Frage. Tomasz vor 6 Jahren 0
Fügen Sie "second / path / a = foo / bar / time = 001.jpg" dem vom OP bereitgestellten Set hinzu. Es endet nach `first / path / time = 002.jpg` wegen des zusätzlichen` = `. Ihre Antwort kann für das OP ausreichen oder nicht ausreichen. Es ist gut, die Einschränkungen zu kennen. Vielleicht ist auch die andere Antwort fehlerhaft; Ich weiß nicht "Rubin" genug, um es zu sagen. Kamil Maciorowski vor 6 Jahren 1
hallo @tomasz, danke für deine Antwort, aber @Kamil sagt, dass es eigentlich nicht für mich funktioniert, da mein tatsächlicher Pfad so etwas wie `first / path / parameter = 1 / time = 001.jpg` ist.` first / path / parameter = 0.1 / time = 001.jpg` `second / path / parameter = 1 / time = 001.jpg` ... :( hadi k vor 6 Jahren 0
@ KamilMaciorowski Guter Punkt, danke. Tomasz vor 6 Jahren 0
@hadik Wenn dies regelmäßig ist und Sie wie dargestellt präsentieren, ändern Sie "-k2" in "-k3". Tomasz vor 6 Jahren 0
@tomasz coole Lösung das hat tatsächlich funktioniert. schöne Kombination von -t und -k, ich habe reguläre Namen, also ist dies der perfekte Dank! :) hadi k vor 6 Jahren 0
Hah, kannte diese Option der Sortierung nicht. +1 mvw vor 6 Jahren 0
@hadik Willkommen. Ich habe auch Perl für die seltsamen Fälle hinzugefügt. Tomasz vor 6 Jahren 0
2
Kamil Maciorowski

Angenommen, kein Pfad ist verrückt genug, um Folgendes zu erfordern find ... -print0:

find . -type f -name "time=*" | awk -F '=' '{ print $NF "=" $0 }' | sort -n | cut -d "=" -f 2- 

Ich habe awkTeile hinter dem Leisten herausgezogen =, er gibt volle Zeilen mit zusätzlichen relevanten Teilen nach vorne aus und trennt sie durch zusätzliche = . Z.B:

001.jpg=path/to/folder1/alpha=0.1_beta=0.2_gamma=1.0/time=001.jpg 

Diese sind numerisch mit sortiert sort. Dann cutextrahiert Teile nach diesem zusätzlichen (ersten) =; Dies sind die ursprünglichen Pfade.

Es gibt genau vier Prozesse erstellt: find, awk, sort, cut. Alternativen, die die Syntax verwenden, find ... -exec some_tool ... \;erstellen einen some_toolProzess pro übereinstimmender Datei.

Ich wusste nicht über "awk", danke für Vorschläge :) hadi k vor 6 Jahren 0
1
mvw

Ein Quickie mit Resten, die ich aus der Kommandozeile ausgewählt habe :-)

find . -name time="*" -exec ruby -e "s='{}'; puts s.split('=')[-1].split('.')[0]+s" \; | sort -n | colrm 1 3 

Erläuterung:

Mein Freund Ruby speichert den von find as angegebenen Pfad {}und speichert ihn in einer Variablen s. Dann teilt sie die Zeichenfolge in =Zeichen auf und behält den letzten Teil (Index -1 im Ergebnis-Array) bei, z 002.jpg. Dann teilt sie diese Zeichenfolge in .Zeichen auf und behält den ersten Teil (Index 0 im Ergebnis-Array) bei, vorausgesetzt, die Dateien werden benannt. Dies ddd.<ext>ergibt den dreistelligen Zahlenteil, z 002.

Zum Schluss druckt sie dies und fügt den ursprünglichen Pfad ein. Das würde geben:

002./alpha=0.1_beta=0.2_gamma=1.0/path/time=002.jpg 001./alpha=0.1_beta=0.2_gamma=1.0/path/time=001.jpg 021./alpha=0.1_beta=0.2_gamma=0.1/path/time=021.jpg 001./alpha=0.1_beta=0.2_gamma=0.1/path/time=001.jpg 019./alpha=0.1_beta=0.2_gamma=0.1/path/time=019.jpg 

Die zusätzlichen Pipe-Befehle sortieren die Ausgabe numerisch ( sort -n) und entfernen schließlich die ersten drei Spalten der Ausgabe ( colrm 1 3).

Beispiel:

test$ find . -name time="*" -exec ruby -e "s='{}'; puts s.split('=')[-1].split('.')[0]+s" \;  | sort -n | colrm 1 3 ./alpha=0.1_beta=0.2_gamma=0.1/path/time=001.jpg ./alpha=0.1_beta=0.2_gamma=1.0/path/time=001.jpg ./alpha=0.1_beta=0.2_gamma=1.0/path/time=002.jpg ./alpha=0.1_beta=0.2_gamma=0.1/path/time=019.jpg ./alpha=0.1_beta=0.2_gamma=0.1/path/time=021.jpg 
Dieses hat das gleiche Problem wie die andere von @tomasz vorgeschlagene Lösung. da mein Pfad mehrere "=" enthält, werden die Zahlen erst nach "=" und dann nach dem zweiten "=" usw. sortiert. Meine Dateien werden also nicht nach meinem Geschmack sortiert. hadi k vor 6 Jahren 0
OK, kann ich das letzte "=" annehmen? (Beachten Sie, dass ich den Index von "1" auf "-1" aktualisiert habe.) mvw vor 6 Jahren 0
@hadik Beachten Sie, dass Sie diese Anforderung zu mehreren "=" hinzugefügt haben, nachdem ich meine erste Version veröffentlicht habe. mvw vor 6 Jahren 0
Es sieht aus wie Rubys für jede gefundene Datei aufgerufen wurde. Tomasz vor 6 Jahren 0
Ja, das war ein schneller Hack. Es ist nicht optimiert. mvw vor 6 Jahren 0
@mvw danke für die Antwort. das funktioniert jetzt, aber die Lösung von tomasz war am einfachsten für mein Problem :) hadi k vor 6 Jahren 0
Zumindest hatte ich 'erste p0st' :-) mvw vor 6 Jahren 1