staging.inyokaproject.org

find

Status: Ungelöst | Ubuntu-Version: Nicht spezifiziert
Antworten |
Dieses Thema ist die Diskussion des Artikels find.

noisefloor Team-Icon

(Themenstarter)

Anmeldungsdatum:
6. Juni 2006

Beiträge: 29567

Hallo,

du hast da was nicht verstanden...

Wenn es um den Befehl find foo geht, dann muss foo ein Verzeichnis im aktuellen Verzeichnis sein.

Falsch. Und:

die Zeilen 3 und 4 zeigen, es gibt eine Datei foo.txt

Nee, eben _nicht_. Es gibt bei dir keine Datei "foo", es gibt eine Datei "foo.txt". Das ist _nicht_ das gleich und nicht das selbe. Wenn es eine Datei Namens "foo" gibt, wird die sehr wohl gefunden.

Der Post von user_unknown hat schon die nötige Substanz und den Bezug zur vorherigen Diskussion.

Präventiv: wenn du verstehen möchtest, warum foo != foo.txt → bitte einen Thread im passenden Supportforum starten und nicht hier.

Gruß, noisefloor

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17630

Berlin_1946 schrieb:

user_unknown schrieb:

So sinnlos ist das nicht.

Wenn man prüfen will, ob die Datei foo älter als 7321 aber jünger als 7327 Tage ist, kann man das mit find sehr gut machen, oder man eine mehr oder weniger wilde Kombination anderer Kriterien, die man mit find testen will; evtl. zielt man auch auf eine der -exec-Varianten ab.

Was hat das vorgenannte jetzt mit der Änderung bzw. mit der aktuellen Diskussion zu tun?

Es gibt für find eine Menge Parameter/Optionen/Argumente, die man übergeben kann. Das erste, wenn es nicht von einem Spiegelstrich begleitet ist, ist der Startpunkt (oder einer der Startpunkte, wenn mehrere angegeben werden).

Der Artikel erklärt die meisten Argumente nicht in Kombination mit anderen, denn bei 30x30 Argumenten kommt man auf 900 Kombinationen, bei 30! Kombinationen auf noch mehr, manche davon sind auch noch reihenfolgesensibel und dürfen mehrfach verwendet werden (-mtime +7320 -mtime -7328).

Dass find foo ohne andere Argumente beschrieben wird heißt nicht, dass es nicht in Kombination mit anderen Argumenten bedacht werden soll. Das Kommando find foo für sich mag nicht sehr sinnvoll aussehen, wenn foo eine einfache Datei ist, aber in Kombination mit anderen Argumenten kann es doch sinnvoll sein, eine Datei zu suchen, z.B. wenn Du nicht 7 oder 70 sondern 70000 Dateien in einem Verzeichnis hast, wenn Du nicht nur eine suchst, sondern mehrere Dutzend, wenn die Suche Teil eines automatisiert laufenden Scripts ist, wenn andere Parameter benutzt werden (Alter, Größe, Besitzer, ...) und die Frage gar nicht ist, ob eine Datei da ist, sondern ob sie diesen Kriterien entspricht, die nicht trivial mit ls -l foo ablesbar sind.

Hier wurden nie über die Punkt "alte, jünger und/oder Tage" diskutiert.

Jetzt wird es.

Das versehe ich leider auch nicht, wie du das meinst Datei foo.

Wenn es um den Befehl find foo geht, dann muss foo ein Verzeichnis im aktuellen Verzeichnis sein.

Ordinäre Dateien haben meist, aber nicht immer, eine Dateiendung. Unter Linux ist alles eine Datei (bzw. unter unixoiden Systemen), auch ein Verzeichnis, sowie symbolische Links, Sockets und mehr. Müsste foo ein Verzeichnis sein, dann stünde das auch in der Manpage. Die Manpage scheut vor dem Begriff Verzeichnis nicht zurück sondern verwendet ihn extensiv und bemüht sich auch nicht um einen literarischen Stil, bei dem man Wiederholungen eher vermeidet. Es muss also einen Grund geben, wieso von Startpunkten und nicht Startverzeichnissen die Rede ist.

1
2
3
4
5
6
7
mate-hp@matehp-HP:~$ find foo
find: ‘foo’: Datei oder Verzeichnis nicht gefunden
mate-hp@matehp-HP:~$ ls -lauh| grep -i foo
-rw-rw-r--  1 mate-hp mate-hp   14 Feb 13 09:54 foo.txt
mate-hp@matehp-HP:~$ find foo*
foo.txt
mate-hp@matehp-HP:~$

zu:

  1. im Home, dem aktuellen Verzeichnis wird find foo aufgerufen

  2. nichts gefunden. Datei oder Verzeichnis nicht gefunden

  3. die Zeilen 3 und 4 zeigen, es gibt eine Datei foo.txt

  4. wenn Dateien gefunden werden sollen, dann ist das der Befehl find foo* (siehe auch das Beispiel find Film* in diesem Wiki)

Wie gesagt, die Startpunkte legen fest, wo gesucht wird, nicht was gesucht wird. Wenn aber alle Startpunkte Dateien sind, die, selbst wenn es Ziparchive o.ä. sind, nicht ihrerseits durchsucht werden, dann findet find nur diese Startpunkte und zeigt sie an.

Wenn es aber ein Verzeichnis gibt, das dem Muster Film* entspricht, wird alles in dem Verzeichnnis und seinen Unterverzeichnissen gefunden, Film* ist nur der Startpunkt.

Wenn Du wirklich nur auf der aktuellen Ebene und nicht in Unterverzeichnissen suchen willst, kannst Du das mit -maxdepth 1 einschränken. Wenn Du nach einer Datei namens foo suchst also find -maxdepth 1 -name foo, aber mit foo(Tab Tab) bist Du sicher schneller, wenn es nur darum geht, ob die Datei da ist oder nicht. Oder ls -d foo.

Das Wort "Verzeichnisse" (also Mehrzahl) ist aus meiner Sicht richtig , zeigt doch dieses andere Beispiel:

Das Wort war aber "Verzeichnisses".

find foo

sucht in foo im aktuellen Verzeichnisses.

Vielleicht hieß es mal

sucht in foo des aktuellen Verzeichnisses.

der Befehl find foo zeigt:

mate-hp@matehp-HP:~$ find foo
foo # ist ein Verzeichnis im Home (~)
foo/foo1 # ist ein Verzeichnis im  Verzeichnis `foo` 
foo/foo1/foo1.txt # Datei im  Verzeichnis `foo1`
foo/foo3.txt
foo/.~lock.foo.txt#
foo/foo2 # ist ein Verzeichns im  Verzeichnis `foo`
foo/foo2/foo2.txt # Datei im  Verzeichnis `foo2`
mate-hp@matehp-HP:~$ 

Find würde auch foo/bar/baz.txt finden, wenn Du find foo eingibst, weil alle Dateien im Verzeichnis foo dem Suchkriterium entsprechen.

Ins Verzeichnis foo gewechselt,

Codemate-hp@matehp-HP:~/foo$ ls -lauh| grep -i foo
drwxrwxr-x  2 mate-hp mate-hp 4,0K Feb 13 10:23 foo1
drwxrwxr-x  2 mate-hp mate-hp 4,0K Feb 13 10:23 foo2
-rw-rw-r--  1 mate-hp mate-hp   14 Feb 13 09:54 foo3.txt
-rw-rw-r--  1 mate-hp mate-hp   79 Feb 13 09:54 .~lock.foo.txt#
mate-hp@matehp-HP:~/foo$ 

ist zu sehen, das es 2 Verzeichnisse gibt (gelb markiert).

Ja, und ein Verzeichnis bar1 wäre auch gefunden worden.

Ich erkenne bei:find foo

foo muss ein Verzeichnis im aktuellen Verzeichnis sein. Der Startpunkt ist das Verzeichnis foo in dem wird rekursiv nach allen Verzeichnissen und Daten gesucht die foo enthalten.

Das ist falsch, und Du begehst den confirmation bias: Du suchst nur nach Belegen, die Deine These stützen. Du müsstest nach Belegen suchen, die Deine These falsifizieren - Du wärst überrascht, wie schnell sie falsifiziert ist!

Und noch ein Beispiel:

Auch das ist schlecht, weil es nicht widerlegt und so wie angelegt ist auch nicht widerlegen kann, dass der Startpunkt nur festlegt, wo gesucht wird, nicht was gesucht wird.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
t530:~/tmp 🐧> mkdir test
t530:~/tmp 🐧> cd test
t530:~/tmp 🐧> mkdir foo bar
t530:~/tmp/test 🐧> touch {foo,bar}"/"{foo,baz}
t530:~/tmp/test 🐧> tree 
.
├── bar
│   ├── baz
│   └── foo
└── foo
    ├── baz
    └── foo

2 directories, 4 files
t530:~/tmp/test 🐧> find foo 
foo
foo/foo
foo/baz

Erklärung: Der Startpunkt ist foo, und alles darin wird gefunden, inklusive des Startpunktes selbst und der Datei baz.

In bar wird nichts gefunden, auch foo nicht. Erklärung: Da wird gar nicht gesucht.

Sry aber diesen Zusammenhang kann ich leider nicht in diesem Satz

- sucht in foo im aktuellen Verzeichnis.-

erkennen, auch wenn ich vorher Startpunkt gelesen habe.

Berlin_1946 Team-Icon

Supporter, Wikiteam

Anmeldungsdatum:
18. September 2009

Beiträge: 10477

noisefloor schrieb:

die Zeilen 3 und 4 zeigen, es gibt eine Datei foo.txt

Nee, eben _nicht_. Es gibt bei dir keine Datei "foo", es gibt eine Datei "foo.txt".

Sry, ich habe nicht geschrieben, dass es eine Datei "foo" gibt, sondern "es gibt eine Datei foo.txt"

Präventiv: wenn du verstehen möchtest, warum foo != foo.txt → bitte einen Thread im passenden Supportforum starten und nicht hier.

Wie du schreibst, habe ich das nicht verstanden, es hilft mir, wenn du mir bitte das passenden Supportforum mitteilen könntest.

Danke in Voraus.

@user_unknown

Ordinäre Dateien haben meist, aber nicht immer, eine Dateiendung. Unter Linux ist alles eine Datei (bzw. unter unixoiden Systemen), auch ein Verzeichnis, sowie symbolische Links, Sockets und mehr

mit dieser Aussage macht das gleich für mich einen anderen "Sinn"

mate-hp@matehp-HP:~$ find foo
find: ‘foo’: Datei oder Verzeichnis nicht gefunden
mate-hp@matehp-HP:~$ ls

Ich habe einfach unterstellt "Datei" sein eine "Ordinäre Datei".

Ich glaube da hat es klick gemacht. 😲

Du begehst den confirmation bias: Du suchst nur nach Belegen, die Deine These stützen.

Das war keinesfalls mein Ansatz. Ich habe ein Beispiel erstellt, um es genauer zu verstehen. Ich habe das halt genau so erstellt, wie ich geglaubt habe, das es funktioniert. Erst dein Beispiel hilft mir, es besser zu verstehen. Danke.

Hier wurden nie über die Punkt "alte, jünger und/oder Tage" diskutiert.

Jetzt wird es.

Da habe ich es zu krass geschrieben, sry.

Ich habe leider keinen Zusammenhang zwischen meiner Frage und deiner Antwort herstellen können.

Ich bemühe mich, etwas diplomatischer zu schreiben. 😛

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17630

Berlin_1946 schrieb:

@user_unknown

Ordinäre Dateien haben meist, aber nicht immer, eine Dateiendung. Unter Linux ist alles eine Datei (bzw. unter unixoiden Systemen), auch ein Verzeichnis, sowie symbolische Links, Sockets und mehr

mit dieser Aussage macht das gleich für mich einen anderen "Sinn"

Prima. ☺

Ich habe einfach unterstellt "Datei" sein eine "Ordinäre Datei".

Ich glaube da hat es klick gemacht. 😲

Dann hat sich die Diskussion ja gelohnt.

(...) Da habe ich es zu krass geschrieben, sry.

Oh, kein Problem.

Ich bemühe mich, etwas diplomatischer zu schreiben. 😛

Na, ich bin auch nicht immer der diplomatischste.

Berlin_1946 Team-Icon

Supporter, Wikiteam

Anmeldungsdatum:
18. September 2009

Beiträge: 10477

Danke das du in die Diskussion eingestiegen bis.

Ich habe hiermit noch nicht gearbeitet.

touch {foo,bar}"/"{foo,baz}

falls es den Regel widerspricht, bitte ich schon vorab um Verzeihung

In der "man" zu touch habe ich es nicht gefunden (das gelb markierte)

Hast du einen Link wie das wirkt oder kannst du es mir hier erklären?

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17630

Du findest es nicht in der Manpage von touch, weil es, bevor touch es zu sehen bekommt, schon von der Shell expandiert wird.

Du kannst

1
2
3
echo {1..3}
echo {7..15}
echo {7..15..2}

erst mal so in der Shell ausprobieren, wie auch

1
2
echo {a..d}
echo {P..d}

oder

1
echo {foo,bar,baz}

bevor Du dann Konstruktionen mit mehreren geschweiften Klammern testest.

Was leider nicht geht ist Variablenexpansion in geschweiften Klammern, wie

1
2
3
a=9
echo {5..$a}
echo {5..a}

was an der Reihenfolge liegt, in der die Bash die einzelnen Syntaxelemente auswertet.

Um schließlich elaborierte Konstruktionen zu starten:

1
echo -e {Peter,Paul,Mary}" "{Meier,Müller,Schulz}", "{9..11}" "{j..m}"\n" 
  • praktisch zur Testfallgenerierung.

In der manpage der Bash findet sich eine, leicht spröde, Erklärung unter Brace Expansion.

linux_joy

Anmeldungsdatum:
6. Februar 2008

Beiträge: 803

Hallo zusammen,

der Vollständigkeit halber sollte m.E. noch auf Desktopsuchmaschinen verwiesen werden, und zwar in den Abschnitten:

  • (Einleitung); am Ende z.B.:

    • Wie man alle Dateiinhalte eines Ordners nach einem bestimmten Wort durchsuchen kann, erklärt der Artikel Desktopsuchmaschinen.

  • Links; z.B.:

    • Desktopsuchmaschinen - Auffinden bzw. Herausfiltern von Begriffen innerhalb unterschiedlichster Dateitypen



Anmerkung:
Dieser Beitrag wurde wg. des jeweils gleichen Zweckes mehrfach gepostet, und zwar in den Diskussionen der Artilel find und locate.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17630

Ich habe dann mal die Abschnitte zu find und locate bei Desktopsuchmaschinen überarbeitet. Neben sprachlichen Korrekturen (Geschlecht, fehlendes Wort) v.a. präzisiert, lang die locate-Datenbank braucht, um neue Dateien aufzunehmen und das schlechte Beispiel "neu installierte Programme" rausgeworfen - deren Installation triggert ja meist die Aktualisierung der updatedb.

Und mit find kann man nicht für die Funde ein Programm dann aufrufen, sondern so viele, wie der Tastaturpuffer hergibt.

linux_joy

Anmeldungsdatum:
6. Februar 2008

Beiträge: 803

Hallo user_unknown, Du schriebst:

Ich habe dann mal die Abschnitte zu find und locate bei Desktopsuchmaschinen überarbeitet. (...)

Vielen Dank dafür. Allerdings gelten meine Vorschläge ja direkt für find und locate.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17630

Im Abschnitt "Verkettung von Kommandos" habe ich die Dateinamensmuster in Anführungsstriche gesetzt, siehe oben, Kriterium "-name".

Für meinen Geschmack ist find ja schwer genug, da muss man nicht noch ffmpeg, dessen Syntax viele Leser des Artikels wohl nicht kennen, hinzunehmen, ... - nach dem ersten -exec kann man auch weitere Kriterien einführen und ausschließlich für große Bilder Thumbnails on the fly generieren usw. ☺ ...

Aber gut.

1
find "*.jpg" ... 

findet jedenfalls, falls im aktuellen Verzeichnis eine Datei 1234.jpg ist, in allen Unterverzeichnissen dann auch nur 1234.jpg-Dateien. Ist zufällig keine jpg-Datei im pwd, dann wird der * nicht ersetzt und von find brav gesucht.

(Korrigiert).

Das Kürzen von Shellbefehl findet meine uneingeschränkte Zustimmung.

UlfZibis

Anmeldungsdatum:
13. Juli 2011

Beiträge: 3351

user_unknown schrieb:

Für meinen Geschmack ist find ja schwer genug, da muss man nicht noch ffmpeg, dessen Syntax viele Leser des Artikels wohl nicht kennen, hinzunehmen, ... - nach dem ersten -exec kann man auch weitere Kriterien einführen und ausschließlich für große Bilder Thumbnails on the fly generieren usw. ☺

... Ja, kompliziert, aber bei solch komplizierten Befehlen zeigt sich eben, dass man da mit mehrfachen -exec hintereinander nicht weiterkommt. Mein erster Versuch scheiterte ja:

find *.flac -print -exec x="{}" \; -exec ffmpeg -i "$x" -q 2 "${x/.flac/.mp3}" \; -exec touch -r "$x" "${x/.flac/.mp3}" \; 
1
find "*.jpg" ... 

findet jedenfalls, falls im aktuellen Verzeichnis eine Datei 1234.jpg ist, in allen Unterverzeichnissen dann auch nur 1234.jpg-Dateien. Ist zufällig keine jpg-Datei im pwd, dann wird der * nicht ersetzt und von find brav gesucht.

Andererseits:

.../Artwork$ find "*.jpg"
find: ‘*.jpg’: Datei oder Verzeichnis nicht gefunden
.../Artwork$ find *.jpg
Back.jpg
CD.jpg
Front.jpg
Leaflet.jpg

Hier müssen die Gänsefüßchen tatsächlich weggelassen werden, sonst funktioniert das nicht.
Diese Besonderheit sollte man an der Stelle vielleicht noch explizit erläutern. Falls Dir dazu eine eine passende Erklärung einfallt, schreib' sie gerne noch an passender Stelle dazu.

Würde ich -name "*.jpg" verwenden, bekäme ich als Ergebnis

./Back.jpg
./CD.jpg
./Front.jpg
./Leaflet.jpg

Damit funktioniert dann aber klein/{} nicht mehr, denn dabei käme dann folgendes raus:

klein/./Back.jpg
klein/./CD.jpg
klein/./Front.jpg
klein/./Leaflet.jpg

Ja und Danke, dass Du da noch mal drüber geguckt hast. 👍

Die Überschrift könnte vielleicht auch ausführlicher so heißen:

  • Verkettung von Kommandos und Ersetzen/Umwandeln (von gefundenen Dateinamen)

Ich dachte, dass es gut wäre, das Thema Verkettung noch dem Artikel beizufügen, denn es war nicht so einfach, die Lösung zu finden, siehe: https://forum.ubuntuusers.de/topic/befehl-um-audio-dateien-zu-konvertieren-mittel

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17630

Ach, da war gar kein -name, und dann habe ich im gleichen Stil geantwortet?

Hm, das war mir gar nicht aufgefallen. Dann muss ich von vorne überlegen.

Das erste Beispiel war doch:

1
find *.jpg -exec convert {} -quality 80% klein/{} \; -exec touch -r {} klein/{} \; 

und findet also überhaupt nur .jpg-Files im aktuellen Verzeichnis, es sei denn es gäbe ein oder mehrere Verzeichnisse des Namens "*.jpg". Unwahrscheinlich, aber möglich.

Aber wieso dann nicht:

1
2
3
4
5
for f in *.jpg
do
    convert $f -quality 80% klein/$f
    touch -r $f klein/$f
done

Wenn man nicht in die Verzeichnisse absteigt, wozu dann find?

1
2
3
4
5
6
# orig: find */01*.mp3 -print -exec sh -c 'mediainfo "{}" | grep "^Bit rate"' \;
for f in */01*.mp3 
do
  ls $f
  mediainfo $f | grep "^Bit rate"'
done

Hier auch.

Das dritte wohl auch.

kB Team-Icon

Supporter, Wikiteam
Avatar von kB

Anmeldungsdatum:
4. Oktober 2007

Beiträge: 9837

UlfZibis schrieb:

[…] Ich dachte, dass es gut wäre, das Thema Verkettung noch dem Artikel beizufügen

Bitte beachte die Regeln! Solche Hinzufügungen dürfen nicht im freigegebenen Artikel, sondern nur über eine Baustelle erfolgen.

Der Artikel hat etliche formale und inhaltliche Mängel und ist deshalb nun in einer Baustelle.

UlfZibis

Anmeldungsdatum:
13. Juli 2011

Beiträge: 3351

user_unknown schrieb:

Wenn man nicht in die Verzeichnisse absteigt, wozu dann find?

Weil ich dann ein Skript schreiben müsste, was ich mir ersparen wollte. Außerdem wollte ich das in mehreren Verzeichnissen anwenden. Dann hätte ich das Skript immer wieder verschieben müssen und am Schluss müsste ich dran denken, es im Daten-Verzeichnis auch wieder zu löschen.
Ja so gibt es "viele Wege nach Rom" und der mittels find ist einer davon. Die Befehlszeile habe ich automatisch in der bash-Historie, brauche dann keinen Editor zur Verbesserung und kann es nach Verzeichniswechsel dort direkt wieder verwenden, ja sogar Tage später noch. Für das Skript müsste ich mir einen Ablageort suchen. Außerdem bin ich im Skripten nicht so fit, sodass ich dann immer erst auch noch den passenden Artikel suchen muss, der bekanntlich ziemlich länglich ist. Außerdem vergesse ich immer wieder die genaue Syntax für den She-Bang.

Hier auch.

 # orig: find */01*.mp3 -print -exec sh -c 'mediainfo "{}" | grep "^Bit rate"' \; 

Damit geht auch das Absteigen in Verzeichnisse.

Das dritte wohl auch.

Könnte man etwas einfacher machen, indem man gleich lame statt ffmpeg verwendet:

find *.flac -print -exec bash -c 'read x<<<"{}"; lame -V2 "$x" "${x/%.flac/.mp3}" && touch -r "$x" "${x/%.flac/.mp3}"' \; 

Das ist dann auch gleich ein Beispiel, wie man Shellbefehle in find ... -exec verwendet. So eines fehlte IMHO im Artikel.

Aber wo wir gerade dabei sind ... wie kann man denn das vorangestellte "./" im Ergebnis von find vermeiden, wenn man die Option -name verwendet? So einen Hinweis fände ich ziemlich nützlich für den Artikel.

user_unknown schrieb:

Das Kürzen von Shellbefehl findet meine uneingeschränkte Zustimmung.

Besser wäre vielleicht sogar hier "Programm" zu verwenden, da mit -exec ja Programme direkt aufgerufen werden, ohne Shell.

UlfZibis

Anmeldungsdatum:
13. Juli 2011

Beiträge: 3351

kB schrieb:

Bitte beachte die Regeln! Solche Hinzufügungen dürfen nicht im freigegebenen Artikel, sondern nur über eine Baustelle erfolgen.

Wo kann ich die denn nachlesen? Da muss sich wohl was geändert haben. Bisher kannte ich nur die Praxis, dass einfache Ergänzungen direkt vorgenommen wurden.

Der Artikel hat etliche formale und inhaltliche Mängel und ist deshalb nun in einer Baustelle.

Welche?