glaskugel
Anmeldungsdatum: 8. Juli 2010
Beiträge: 3614
|
Ich vereinfache das Beispiel. Es geht um find in einem Bash-Script. Wenn die Verknüpfung oder ist, dann habe ich kein Problem. zB: -regex ".*\(ab\|cd\|ef\|gh\|ij\).*" -name *.txt Wie formuliere ich es, dass die txt.Datei im Namen die Bedinung UND verwendet, also der Dateiname enthält "ab" und "cd" und usw. Die Bedingungen sind einige und das Ergebnis wird an while übergeben. Oder ist es besser das in eine pipe mit grep zu schicken, kommt mir suboptimal vor. Bei meinen Versuchen hat es leider nicht gepasst.
|
kB
Supporter, Wikiteam
Anmeldungsdatum: 4. Oktober 2007
Beiträge: 9579
Wohnort: Münster
|
glaskugel schrieb: […] Wie formuliere ich es, dass die txt.Datei im Namen die Bedinung UND verwendet, also der Dateiname enthält "ab" und "cd" […]
find verknüpft von sich aus alle Argumente mit UND:
find . -regex '.*ab.*' -regex '.*cd.*'
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13146
|
| find -name '*ab*' -name '*cd*' -name '*.txt'
|
Statt while würde ich aber das Skript, das die Fundsachen verarbeitet, direkt von find starten lassen: | find -name '*ab*' -name '*cd*' -name '*.txt' -exec sh -c 'for f;
echo "process $f"
done' -- {} +
|
|
glaskugel
(Themenstarter)
Anmeldungsdatum: 8. Juli 2010
Beiträge: 3614
|
find verknüpft von sich aus alle Argumente mit UND:
So weit klar, aber kann man das "lesbarer" formulieren? Mir w#re so was lieber: oderkriterien="ab,cd,ef,gh,ij" und dann mit "oderkriterien" find aufrufen. Die Anzahl der Kriterien kann bis 10 gehen, meistens nur ein paar. Bei "oder" kann man das wenigstens in Klammern zusammenfassen.
Statt while würde ich aber das Skript, das die Fundsachen verarbeitet, direkt von find starten lassen:
Verstehe ich das richtig, dass ich dann dafür eine weitere Datei brauche? Hintergrund: Das ist ein Script, das alle paar Jahre benötigt wird und einfach Dateien (ca. 50000-100000) nach einer "Logik" automatisch verlinkt, umbenennt und nummeriert. Die Bedingungen sind ziemlich komplex und mehrfach verschachtelt. Theoretisch simpel, in der Praxis gar nicht so einfach. Array ist zu kompliziert bei der Fehlersuche. Suche gerade nach 3 Fehlern, weil das Ergebnis bei 20x100 ok ist.
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4661
Wohnort: Berlin
|
@glaskugel Die weitere Datei könnte auch die sein, die Du schon hast. Man kann ja Argumente übergeben die entscheiden was das Skript machen soll. Ich persönlich würde ja kompliziertere Sachen einfach nicht mit der Shell machen, sondern ein Programm schreiben. Beispielsweise Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | #!/usr/bin/env python3
from pathlib import Path
def main():
base_path = Path("...")
for path in base_path.rglob("*.txt"):
path_text = str(path)
if all(part in path_text for part in ["ab", "cd", "ef", "gh", "ij"]):
print(path)
if __name__ == "__main__":
main()
|
Oder mit einer zusätzlichen Funktion:
| def contains_all(path, parts):
path_text = str(path)
return all(part in path_text for part in parts)
def main():
base_path = Path("...")
for path in base_path.rglob("*.txt"):
if contains_all(path, ["ab", "cd", "ef", "gh", "ij"]):
print(path)
|
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13146
|
glaskugel schrieb: find verknüpft von sich aus alle Argumente mit UND:
So weit klar, aber kann man das "lesbarer" formulieren? Mir w#re so was lieber: oderkriterien="ab,cd,ef,gh,ij" und dann mit "oderkriterien" find aufrufen.
Das ist jetzt verwirrend: Du willst doch eine UND-Verknüpfung. Der Variablenname legt aber etwas anderes nahe. Dann müsstest Du $undkriterien parsen und daraus eine Kommandozeile für find erzeugen. Das könnte man so machen, ist aber etwas fragil, weil es Sonderzeichen nicht beachtet und damit ungültige Ausgaben produzoeren kann: | undkriterien=ab,cd,ef,gh,ij
find $(echo "$undkriterien" | sed 's#[^,]\+#-name &#g; s#,# #g' )
|
Eine andere, robustere Möglichkeit ist ein Array: | undkriterien=(ab cd ef gh ij)
args=()
for k in "${undkriterien[@]}"; do
args+=(-name "$k")
done
find "${args[@]}"
|
Aber dann kann man die Kriterien auch einfach direkt in den find -Aufruf hineinschreiben.
Statt while würde ich aber das Skript, das die Fundsachen verarbeitet, direkt von find starten lassen:
Verstehe ich das richtig, dass ich dann dafür eine weitere Datei brauche?
Nein, die Logik geht in den Rumpf der for -Schleife, die ich gezeigt habe.
Hintergrund: Das ist ein Script, das alle paar Jahre benötigt wird und einfach Dateien (ca. 50000-100000) nach einer "Logik" automatisch verlinkt, umbenennt und nummeriert. Die Bedingungen sind ziemlich komplex und mehrfach verschachtelt. Theoretisch simpel, in der Praxis gar nicht so einfach. Array ist zu kompliziert bei der Fehlersuche. Suche gerade nach 3 Fehlern, weil das Ergebnis bei 20x100 ok ist.
Das hilft mir nicht so viel. Aber so etwas würde ich dann wohl in Ruby schreiben. Wie viele Zeilen hat denn Dein Skript?
|
glaskugel
(Themenstarter)
Anmeldungsdatum: 8. Juli 2010
Beiträge: 3614
|
Das hilft mir nicht so viel. Aber so etwas würde ich dann wohl in Ruby schreiben.
nicht mit der Shell machen, sondern ein Programm schreiben. Beispielsweise Python:
Tja, das ist genau das Problem, mehrere verschiedene familiäre Umstände lassen mir keine Zeit eine Programmiersprache zu lernen, habe das seit 10 Jahren am Plan. Daher auch die späte Antwort. Ich bin froh, wenn ich Kleinigkeiten mit der Bash schaffe und irgendwie klappt es dann schon mit der Bash, ob schön programmiert ist ein anderes Thema
Wie viele Zeilen hat denn Dein Skript?
Schwer zu sagen was wirklich notwendig ist, aber ich bin so bei 2000 Zeilen. Um besser testen zu können, schreibe ich jetzt manches nicht in eine Pipe, sondern in mehrere Zeilen. Ist schlimm das Problem zu finden, wenn es meistens funktioniert. Solange ich reduziert teste, läuft es fehlerlos, mit allen Daten sind dann ein paar falsch. Das Problem liegt also primär bei mir beim Definieren der Regeln, Ausnahmen, etc. Wenn ich einen Denkfehler habe, muss ich das Problem vor dem Schreiben des Codes erkennen und da kann mir keiner helfen. Ich mache es jetzt umständlich um besser testen zu können, Hauptsache es gibt am Ende keinen Fehler. Das letzte Mal hatte ich das Script vor 3 Jahren gebraucht. Da ist es völlig egal, wenn es ein paar Sekunden länger braucht, aber manchmal habe ich den Anreiz es schöner zu schreiben.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13146
|
Bin jetzt etwas ratlos. Ich habe noch kein Feedback auf meine Vorschläge bekommen bzw. eine Aussage, warum das so nicht geht. Es wäre auch vielleicht hilfreich zu wissen, was das Programm / Skript eigentlich inhaltlich macht / machen soll.
|
micneu
Anmeldungsdatum: 19. Januar 2021
Beiträge: 723
Wohnort: Hamburg
|
glaskugel schrieb: Hintergrund: Das ist ein Script, das alle paar Jahre benötigt wird und einfach Dateien (ca. 50000-100000) nach einer "Logik" automatisch verlinkt, umbenennt und nummeriert. Die Bedingungen sind ziemlich komplex und mehrfach verschachtelt. Theoretisch simpel, in der Praxis gar nicht so einfach. Array ist zu kompliziert bei der Fehlersuche. Suche gerade nach 3 Fehlern, weil das Ergebnis bei 20x100 ok ist.
Für was für ein Programm sind die daten (bitte mehr Informationen)? Um welche daten Menge sprechen wir bei den ca. 50000 – 100000 Dateien? Hast du einen github Zugang, dann packe es doch mal hin und poste den link zu deinem script, ich bin neugierig was genau dein script alles macht Ich persönlich würde, wenn es wirklich so komplex ist wie du schreibst auch zu einer Programmiersprache greifen wie python, als ich damit anfing habe ich schon nach 3 stunden die ersten Erfolge gehabt.
|
glaskugel
(Themenstarter)
Anmeldungsdatum: 8. Juli 2010
Beiträge: 3614
|
Für was für ein Programm sind die daten
Sind eigentlich nur Dateinamen, die analysiert werden, wobei die Dateinamen schon eine spezielle Logik haben und hier fangen die Probleme an.
Um welche daten Menge sprechen wir bei den ca. 50000 – 100000 Dateien?
Habe heute noch mal suchen lassen, Ergebnis sind ca. 120000 Dateien
bin neugierig was genau dein script alles macht
Wenn du so willst, "primitivste künstliche Intelligenz" = interne Logik um die Dateien zu gruppieren und unterwegs zu wissen, was bei Bedarf vorhanden ist, zB Fotos von einem CT, das sind pro Untersuchung schnell über 1000 und da werden die Metadaten ausgewertet, aber auch andere Dateien.
als ich damit anfing habe ich schon nach 3 stunden die ersten Erfolge gehabt.
Mein Bash-Script tut jetzt auch was es soll. Ich habe nicht den Kopf genug frei mich in was neues rein zu denken, würde ich gerne. Die Bash-Scripts müssen auch irgendwie nebenbei erstellt werden. Die Daten sind vertraulich, ich kann da nichts hochladen.
|
micneu
Anmeldungsdatum: 19. Januar 2021
Beiträge: 723
Wohnort: Hamburg
|
Ok, also handelt es sich um dicom Daten/dateien?
Wenn ich mich richtig erinnere haben dicom Daten sowas ähnliches wie EXIF.
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4661
Wohnort: Berlin
|
@glaskugel Das ist ein inkonsistentes Argument keine Zeit zu haben etwas zu lernen was einfacher ist, aber die Zeit zu haben ein komplexes Bash-Skript zu warten und weiterzuentwickeln, und sich Notlösungen zu basteln für komplexere Dinge für die Bash einfach nicht gedacht und damit auch nicht wirklich geeignet ist. Zudem muss man bei Bash in der Regel mehrere Sprachen lernen, denn man benutzt da ja immer wieder Werkzeuge aus Shell-Skripten heraus die ihre eigene(n) kleinen oder auch grösseren Sprachen mitbringen, wie AWK, sed, grep, bc, und so weiter, deren Funktionalität man in einer ordentlichen Sprache schon in der Sprache hat. Ausgenommen vielleicht reguläre Ausdrücke, die nicht alle Sprachen als Sprachkonstrukt haben, dann aber in der Standardbibliothek. Und da muss man dann nur eine Geschmacksrichtung lernen.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13146
|
Marc_BlackJack_Rintsch schrieb: Ausgenommen vielleicht reguläre Ausdrücke, die nicht alle Sprachen als Sprachkonstrukt haben, dann aber in der Standardbibliothek.
Deshalb erledige ich solche Aufgaben immer in Ruby: da hat man Reguläre Ausdrücke als Sprachkonstrukt und man kann sie sogar über mehrere Zeilen laufen lassen und mit Kommentaren versehen. Davon ab hat die Standardbibliothek alles, was man für solche Aufgaben typischerweise braucht (Hash, Find.find(), File.stat()...).
|
glaskugel
(Themenstarter)
Anmeldungsdatum: 8. Juli 2010
Beiträge: 3614
|
Danke für die Hinweise. Jetzt brauche ich nur mehr die Zeit mich da einzuarbeiten. Da das Script nun das tut was es soll, ist die Motivation leider gering, wenn man sich um Pflegefälle kümmern muss.
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4661
Wohnort: Berlin
|
@rklm: Kann man in Python auch machen. Ich denke nicht, dass es wirklich wichtig ist das reguläre Ausdrücke eine eigene Syntax in der Sprache haben, solange es was in der Standardbibliothek dafür gibt. Ansonsten wäre auch JavaScript verbreitet und notfalls wäre sogar PHP besser als Bash. Eben alles was nicht nur Zeichenketten kennt und alle naselang versucht irgendwelche Automatismen anzuwenden, gegen die man sich wehren muss, wenn man die gar nicht haben will.
|