per bash feststellen ob Dateityp in Verzeichnis

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
curt123
Beiträge: 704
Registriert: 19.10.2018 12:49:35
Wohnort: NRW

per bash feststellen ob Dateityp in Verzeichnis

Beitrag von curt123 » 13.11.2021 16:49:39

Hallo,

ich möchte feststellen, ob ein bestimmter Dateityp in Verzeichnis vorhanden ist.

Bei meinem konkreten Anwendungsfall geht das über den Dateinamen bzw. Abfrage des vorhandenen Suffix. Dazu habe ich verschiedenen Beispielcode gefunden, der mir umständlich vorkam und/oder nicht so richtig funktioniert hat. Schließlich habe ich bei diesem Code

Code: Alles auswählen

if [ ${#files[@]} -gt 0 ]

gesehen, dass eine Afrage wie nach *.txt im Array bei leerem Verzeichnis ein Element "*.txt" erzeugt.
Die Lösung sieht jetzt so aus:

Code: Alles auswählen

is_in_dir () {
   files=("$1")
   if [ ${#files[@]} -gt 0 ] && [[ ${files[0]} != *"*"* ]] 
   then
      echo 1
   else
      echo 0
   fi
}

echo $(is_in_dir ./*.txt)
Vielleicht könnte ich je nach Anwendungsfall noch sicherstellen, dass kein Unterverzeichnis mit passendem Namen miterfasst wird.
Abgesehen davon, ob die Lösung verläßlich oder "sauber" ist, interessiert mich der Eintrag bei fehlender Datei.
Ist das ähnlich wie bei der folgenden Meldung?

Code: Alles auswählen

ls *.txt
ls: Zugriff auf '*.txt' nicht möglich: Datei oder Verzeichnis nicht gefunden

JTH
Moderator
Beiträge: 3077
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: per bash feststellen ob Dateityp in Verzeichnis

Beitrag von JTH » 13.11.2021 17:36:08

curt123 hat geschrieben: ↑ zum Beitrag ↑
13.11.2021 16:49:39
Schließlich habe ich bei diesem Code

Code: Alles auswählen

if [ ${#files[@]} -gt 0 ]

gesehen, dass eine Afrage wie nach *.txt im Array bei leerem Verzeichnis ein Element "*.txt" erzeugt.
Ja, das ist richtig. Wenn keine Datei oder Ordner existiert, der auf das Muster passt, bleibt das Muster „wörtlich“ stehen. Das kann man mit

Code: Alles auswählen

shopt -s nullglob
abschalten, dann wird das nicht-treffende Muster zu einem leeren String. Die Option ist allerdings, meine ich, ein reines Bash-Feature.


curt123 hat geschrieben: ↑ zum Beitrag ↑
13.11.2021 16:49:39
Die Lösung sieht jetzt so aus:

Code: Alles auswählen

is_in_dir () {
   files=("$1")
   if [ ${#files[@]} -gt 0 ] && [[ ${files[0]} != *"*"* ]] 
   then
      echo 1
   else
      echo 0
   fi
}

echo $(is_in_dir ./*.txt)
Das wird nicht ganz funktionieren. Edit: Korrigiere, das funktioniert, aber nur weil du das ./*.txt beim Aufruf der Funktion nicht gequotet hast. Die Pfad-Expansion (Dateipfad mit nem * drin) ist eine der wenigen Zeichenketten, die man nicht in Quotes verpacken darf, sonst verliert sie ihre Funktion (also nur das Sternchen darf nicht in Quotes stehen, der Rest bei Bedarf schon). So hast du auch immer nur ein Array mit genau einem Element, *.ext.

Du lädst damit (mit korrekt nicht-gequotetem $1) auch immer alle Ordnerelemente in das Array, das kann unnötige Arbeit sein.

Ein paar Alternativen, die mir spontan einfallen:
Mit find, damit kannst du das auch gleich mit -type f auf nur Dateien reduzieren:

Code: Alles auswählen

is_in_dir()
{
	# Hier muss man beides quoten, da find hier das Muster benutzen soll, nicht die Shell.
	# Ausrufezeichen am Anfang ist wichtig.
	! find "$1" -maxdepth 1 -type f -name "$2" -exec false {} + -quit
}

is_in_dir /some/dir "*.txt" && echo "Found one!"

Mit ls ohne weitere Einschränkung:

Code: Alles auswählen

is_in_dir()
{
	ls $1 >/dev/null 2>&1
}

is_in_dir "/some/dir/*.txt" && echo "Found one!"

Reine Shell, auch mit Einschränkung auf Dateien, mit frühem return, sobald eine passende Datei gefunden wurde:

Code: Alles auswählen

is_in_dir()
{
	for f in $1; do
		[ -f "$f" ] && return 0
	done
	
	return 1
}

is_in_dir /some/dir "*.txt" && echo "Found one!"
Ich vermute mal, dass diese Variante die schnellste ist.

Die letzten beiden Varianten, also außer der mit find, funktionieren so nicht mit Pfaden mit Leerzeichen.

curt123 hat geschrieben: ↑ zum Beitrag ↑
13.11.2021 16:49:39
Abgesehen davon, ob die Lösung verläßlich oder "sauber" ist, interessiert mich der Eintrag bei fehlender Datei.
Ist das ähnlich wie bei der folgenden Meldung?
Das versteh ich nicht so ganz. Wenn keine passende Datei gefunden wurde, möchtest du den Namen eines Ordners haben, der zum Muster passt?
Zuletzt geändert von JTH am 14.11.2021 00:55:06, insgesamt 3-mal geändert.
Grund: Lösung mit find korrigiert
Manchmal bekannt als Just (another) Terminal Hacker.

curt123
Beiträge: 704
Registriert: 19.10.2018 12:49:35
Wohnort: NRW

Re: per bash feststellen ob Dateityp in Verzeichnis

Beitrag von curt123 » 13.11.2021 19:23:10

Danke für die Beispiele, ich schau mir das nachher oder morgen noch gründlicher an. Ich brauche keine Ausgabe der jeweiligen Dateien, sondern nur 1 bei der ersten Datei (oder sonst ggf. 0) ; vielleicht wäre bei einer for-Schleife ein echo 1 und break beim ersten Treffer interessant.
JTH hat geschrieben: ↑ zum Beitrag ↑
13.11.2021 17:36:08
curt123 hat geschrieben: ↑ zum Beitrag ↑
13.11.2021 16:49:39
Abgesehen davon, ob die Lösung verläßlich oder "sauber" ist, interessiert mich der Eintrag bei fehlender Datei.
Ist das ähnlich wie bei der folgenden Meldung?
Das versteh ich nicht so ganz. Wenn keine passende Datei gefunden wurde, möchtest du den Namen eines Ordners haben, der zum Muster passt?
Ich wollte das hier unerwünschte Auftauchen der Abfrage (also z.B. des *.txt) im eigentlich leeren Array mit der nicht-gefunden Meldung von ls vergleichen. Wenn ich ein zeilenweise ausgegebenes Suchergebnis auswerten würde, müßte ich den Fall auch rausfiltern.
JTH hat geschrieben: ↑ zum Beitrag ↑
13.11.2021 17:36:08
Du lädst damit (mit korrekt nicht-gequotetem $1) auch immer alle Ordnerelemente in das Array, das kann unnötige Arbeit sein.
Da sind mir die Zusammenhänge noch nicht ganz klar.
Wenn die Funktion weniger vielseitig sein darf, könnte ich den Suffix, also z.B. txt, gequotet übergeben, und das Sternchen erst in der Funktion dazunehmen, und müßte dann beim nichts-gefunden Zustand kein erstes Element *.txt im Array berücksichtigen?

JTH
Moderator
Beiträge: 3077
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: per bash feststellen ob Dateityp in Verzeichnis

Beitrag von JTH » 14.11.2021 00:52:52

curt123 hat geschrieben: ↑ zum Beitrag ↑
13.11.2021 19:23:10
Danke für die Beispiele, ich schau mir das nachher oder morgen noch gründlicher an. Ich brauche keine Ausgabe der jeweiligen Dateien, sondern nur 1 bei der ersten Datei (oder sonst ggf. 0) ; vielleicht wäre bei einer for-Schleife ein echo 1 und break beim ersten Treffer interessant.
Ganz Shell-typisch wäre es für so einen Test, das Ergebnis über eine 1 oder 0 als Rückgabewert der Funktion (deshalb das return oben in der dritten Variante) weiterzugeben, nicht über eine echo-Ausgabe einer 1 oder 0. Dann kannst du so eine Funktion ganz praktisch z.B. in einem if benutzen:

Code: Alles auswählen

if ! is_in_dir "/home/curt" "*.txt"; then
    touch /home/curt/Notizen.txt
fi
Auch die beiden Varianten mit find und ls geben nix aus, sondern haben je nach Ergebnis eben einen Rückgabewert. Das funktioniert, weil eine Shell-Funktion den Rückgabewert des letzten Kommandos zurückgibt, wenn kein explizites return auftaucht.


curt123 hat geschrieben: ↑ zum Beitrag ↑
13.11.2021 19:23:10
Ich wollte das hier unerwünschte Auftauchen der Abfrage (also z.B. des *.txt) im eigentlich leeren Array mit der nicht-gefunden Meldung von ls vergleichen. Wenn ich ein zeilenweise ausgegebenes Suchergebnis auswerten würde, müßte ich den Fall auch rausfiltern.
So ganz hab ichs immer noch nicht verstanden, mag an der Uhrzeit liegen :D Du meinst, du hast überlegt da zu Vergleichen, ob die Meldung „ls: Zugriff auf '*.txt' nicht möglich: Datei oder Verzeichnis nicht gefunden“ rauskommt? Oder überlegst welchen Eintrag das Array ohne passende Datei hat? Das wäre wie gesagt dann wörtlich ein Eintrag „*.txt“ o.ä. (Lustig ist, dass man eine Datei mit so einem Namen tatsächlich anlegen könnte, da dreht sichs dann im Kreis :lol: )


curt123 hat geschrieben: ↑ zum Beitrag ↑
13.11.2021 19:23:10
Wenn die Funktion weniger vielseitig sein darf, könnte ich den Suffix, also z.B. txt, gequotet übergeben, und das Sternchen erst in der Funktion dazunehmen, und müßte dann beim nichts-gefunden Zustand kein erstes Element *.txt im Array berücksichtigen?
Hmm, doch, wenn nichts gefunden wurde, hast du auch bei einem längeren Suchpfad /home/curt/*.txt exakt den im Array, wenn keine passende Datei existiert. Egal, ob du das Sternchen erst in der Funktion anhängst oder vorher. Was ich oben schreiben wollte, war hauptsächlich, dass du hier

Code: Alles auswählen

echo $(is_in_dir ./*.txt)
effektiv Folgendes machst – was wahrscheinlich nicht beabsichtigt und erwartet ist:

Code: Alles auswählen

echo $(is_in_dir "./aaa.txt" "./bbb.txt" "./ccc.txt")
Also die Funktion bekommt schon alle aufs Muster passenden Dateinamen übergeben, das geschieht nicht erst in der Funktion selbst. So wäre es „sicher“:

Code: Alles auswählen

echo $(is_in_dir "./*.txt")
Manchmal bekannt als Just (another) Terminal Hacker.

curt123
Beiträge: 704
Registriert: 19.10.2018 12:49:35
Wohnort: NRW

Re: per bash feststellen ob Dateityp in Verzeichnis

Beitrag von curt123 » 14.11.2021 09:20:34

Mit return bei bash für den Fall bin ich noch nicht so ganz glücklich, auch wenn das true für eine if-Abfrage einfacher sein mag. Wobei ich für true eigentlich an 1 (vs 0) denke, und weniger an Errorlevel o.ä..

So schaut es für mich erstmal besser aus; ich vermute einen ähnlichen Ablauf:

Code: Alles auswählen

is_in_dir() {
   for f in $1/$2; do
      if [ -f "$f" ]; then 
         echo 1
         break
      else
         echo 0
      fi
   done
}
Der Aufruf ist z.B. so möglich:

Code: Alles auswählen

$ echo $(is_in_dir /home/curt/Dokumente "*.txt")
1
$ echo $(is_in_dir /home/curt/Dokumente "*.nn")
0
Die if-Abfrage wird (mit 'nicht' und true als 1) etwas umständlicher:

Code: Alles auswählen

if ! [ $(is_in_dir /home/curt/Dokumente "*.txt") -eq 1 ]; then
   touch /home/curt/Dokumente/Notizen.txt
fi

JTH
Moderator
Beiträge: 3077
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: per bash feststellen ob Dateityp in Verzeichnis

Beitrag von JTH » 14.11.2021 13:19:36

curt123 hat geschrieben: ↑ zum Beitrag ↑
14.11.2021 09:20:34
Mit return bei bash für den Fall bin ich noch nicht so ganz glücklich, auch wenn das true für eine if-Abfrage einfacher sein mag. Wobei ich für true eigentlich an 1 (vs 0) denke, und weniger an Errorlevel o.ä..
Was stört dich denn daran? So eine Funktion verwendet man im Großteil der Fälle in eine Test-Kontext (im if oder mit && oder ||), deshalb erleichtert die Rückgabe über den Exitcodes – gerade bei solchen Funktionen – die Anwendung wesentlich. Und wenn du die Werte tatsächlich auf genau 0 und 1 beschränken willst, geht das natürlich auch. Die Exitcodes sind ja nicht nur für Anwendungsfehler, falsche Parameter da, sonder hier halt für den „Fehler" „keine passende Datei gefunden“.

curt123 hat geschrieben: ↑ zum Beitrag ↑
14.11.2021 09:20:34
Die if-Abfrage wird (mit 'nicht' und true als 1) etwas umständlicher:

Code: Alles auswählen

if ! [ $(is_in_dir /home/curt/Dokumente "*.txt") -eq 1 ]; then
   touch /home/curt/Dokumente/Notizen.txt
fi
Und genau deshalb empfiehlt sich die Rückgabe des Ergebnisses über den Exitcode. (Da ist auch eine nicht nötige doppelte Negation drin.)


curt123 hat geschrieben: ↑ zum Beitrag ↑
14.11.2021 09:20:34
So schaut es für mich erstmal besser aus; ich vermute einen ähnlichen Ablauf:

Code: Alles auswählen

is_in_dir() {
   for f in $1/$2; do
      if [ -f "$f" ]; then 
         echo 1
         break
      else
         echo 0
      fi
   done
}
Das ist nicht ganz sauber. Du würdest damit etwa die Ausgabe

Code: Alles auswählen

0
0
0
1
bekommen. Die Funktion funktioniert nur bei einem Verzeichnis mit genau einer Datei, die ins Muster passt.
Du willst da nur genau eine Ausgabe haben, etwa so:

Code: Alles auswählen

is_in_dir() {
   for f in "$1/"$2; do
      if [ -f "$f" ]; then 
         echo 1
         return
      fi
   done
   echo 0
}

curt123 hat geschrieben: ↑ zum Beitrag ↑
14.11.2021 09:20:34
Der Aufruf ist z.B. so möglich:

Code: Alles auswählen

$ echo $(is_in_dir /home/curt/Dokumente "*.txt")
Warum doppelt gemoppelt? ;) (Auch wenns nur ein Beispiel ist.) Kein Grund für das redundante echo:

Code: Alles auswählen

is_in_dir /home/curt/Dokumente "*.txt"
Manchmal bekannt als Just (another) Terminal Hacker.

curt123
Beiträge: 704
Registriert: 19.10.2018 12:49:35
Wohnort: NRW

Re: per bash feststellen ob Dateityp in Verzeichnis

Beitrag von curt123 » 14.11.2021 14:18:51

JTH hat geschrieben: ↑ zum Beitrag ↑
14.11.2021 13:19:36
Was stört dich denn daran?
Müßte ich nochmal drüber nachenken. Individuelle Ästhetik? Irgendwie "besserer" Code oder nicht? Nur Gewohnheit?
(Da ist auch eine nicht nötige doppelte Negation drin.)
Das war Absicht als Bezug auf dein Beispiel.
Das ist nicht ganz sauber. Du würdest damit etwa die Ausgabe

Code: Alles auswählen

0
0
0
1
bekommen. Die Funktion funktioniert nur bei einem Verzeichnis mit genau einer Datei, die ins Muster passt.
Dafür sollte break zuständig sein.
Warum doppelt gemoppelt? ;) (Auch wenns nur ein Beispiel ist.)
Auch weil es ein Beispiel ist ;) Mit der sparsamen Ausführung dürfte der Vorteil der anderen Lösung auch noch geringer werden.

Ich habs auch noch so probiert:

Code: Alles auswählen

$ ls -1 *.txt | wc -l
13
$ is_in_dir() {
   for f in $1/$2; do
      if [ -f "$f" ]; then 
         echo 1
         break
      else
         echo 0
      fi
   done }
$ is_in_dir ./ "*.txt"
1
$ is_in_dir ./ "*.nn"
0
Zuletzt geändert von curt123 am 14.11.2021 15:21:45, insgesamt 1-mal geändert.

Benutzeravatar
heinz
Beiträge: 535
Registriert: 20.12.2007 01:43:49

Re: per bash feststellen ob Dateityp in Verzeichnis

Beitrag von heinz » 14.11.2021 15:14:05

Wie waere es hiermit?

Code: Alles auswählen

is_in_dir() {
  ls $1/$2 2>/dev/null 1>&2 && echo 1 || echo 0
}

is_in_dir ./ "*.txt"
is_in_dir ./ "*.nn"

Benutzeravatar
Meillo
Moderator
Beiträge: 9241
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: per bash feststellen ob Dateityp in Verzeichnis

Beitrag von Meillo » 14.11.2021 16:40:20

Wie waere es damit:

Code: Alles auswählen

if [ "`echo *.txt`" != "*.txt" ] ; then
	echo enthalten
else
	echo fehlt
fi
... mal als alternativen Ansatz. ;-)
Use ed once in a while!

tobo
Beiträge: 2349
Registriert: 10.12.2008 10:51:41

Re: per bash feststellen ob Dateityp in Verzeichnis

Beitrag von tobo » 14.11.2021 17:10:06

Das ist hübsch!

Könnte auch noch kürzen - Eine Funktion, bestehend nur aus der []-Klammmer und ausgestattet mit Positionsparameter.

Benutzeravatar
Meillo
Moderator
Beiträge: 9241
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: per bash feststellen ob Dateityp in Verzeichnis

Beitrag von Meillo » 14.11.2021 17:17:05

tobo hat geschrieben: ↑ zum Beitrag ↑
14.11.2021 17:10:06
Könnte auch noch kürzen - Eine Funktion, bestehend nur aus der []-Klammmer und ausgestattet mit Positionsparameter.
Okay, here we go:

Code: Alles auswählen

have_files_matching() {
	[ "`echo $1`" != "$1" ]
}

Edit: heinz' Vorschlag finde ich aber lesbarer. Den wuerde ich verwenden. Bloss sehe ich keinen Grund den Verzeichnis- und Datei-Anteil aufzutrennen. Das kann ein einziges Argument sein. Und dann gibt es auch keinen Grund die Funktion irgendewas mit ``dir'' zu nennen. (Ich wollte mit meinem Vorschlag nur einen anderen Betrachtungswinkel einbringen.)
Use ed once in a while!

JTH
Moderator
Beiträge: 3077
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: per bash feststellen ob Dateityp in Verzeichnis

Beitrag von JTH » 14.11.2021 17:33:42

Meillo hat geschrieben: ↑ zum Beitrag ↑
14.11.2021 17:17:05
Bloss sehe ich keinen Grund den Verzeichnis- und Datei-Anteil aufzutrennen. Das kann ein einziges Argument sein.
Das kam wohl oben von meinem Vorschlag mit find, da war es notwendig. Wobei man das mit -path, statt -name auch umgehen könnte.

Meillo hat geschrieben: ↑ zum Beitrag ↑
14.11.2021 17:17:05
Und dann gibt es auch keinen Grund die Funktion irgendewas mit ``dir'' zu nennen
Das kam vielleicht von der Anforderung, nur nach Dateien mit dem Muster zu suchen und Ordner zu ignorieren.

curt123 hat geschrieben: ↑ zum Beitrag ↑
14.11.2021 14:18:51
Müßte ich nochmal drüber nachenken. Individuelle Ästhetik? Irgendwie "besserer" Code oder nicht? Nur Gewohnheit?
Ja, das letzte kann ich verstehen. Aus meiner Erfahrung ist es unhandlicher, so etwas primär über Stringvergleiche zu lösen. Wenn man aber die Möglichkeit behalten möchte, kann man ja auch einfach echo und return kombinieren:

Code: Alles auswählen

echo 1
return 0

curt123 hat geschrieben: ↑ zum Beitrag ↑
14.11.2021 14:18:51
Dafür sollte break zuständig sein.

[…]

Ich habs auch noch so probiert:

Code: Alles auswählen

$ ls -1 *.txt | wc -l
13
$ is_in_dir() {
   for f in $1/$2; do
      if [ -f "$f" ]; then 
         echo 1
         break
      else
         echo 0
      fi
   done }
$ is_in_dir ./ "*.txt"
1
$ is_in_dir ./ "*.nn"
0
Auch das klappt so nicht, das echo 0 muss aus der Schleife raus. Und das break ein return werden. Zumindest mit der Anforderung, aufs Muster passende Ordner ignorieren zu können. Die Funktion scheitert sonst z.B. hieran:

Code: Alles auswählen

$ mkdir -p dir dir/{aaa,bbb,ccc}.txt
$ touch dir/{ddd,eee,fff}.txt
$ is_in_dir dir "*.txt"
0
0
0
1
Manchmal bekannt als Just (another) Terminal Hacker.

tobo
Beiträge: 2349
Registriert: 10.12.2008 10:51:41

Re: per bash feststellen ob Dateityp in Verzeichnis

Beitrag von tobo » 14.11.2021 17:38:58

Meillo hat geschrieben: ↑ zum Beitrag ↑
14.11.2021 17:17:05
Bloss sehe ich keinen Grund den Verzeichnis- und Datei-Anteil aufzutrennen.
Wenn ich über verschiedene Endungen in verschiedenen Verzeichnissen iterieren will (2 verschachtelte Schleifen), dann wären 2 Parameter schon ganz praktisch. Zumindest lesbarer als die beiden Schleifenvariablen zusammenzufügen...

curt123
Beiträge: 704
Registriert: 19.10.2018 12:49:35
Wohnort: NRW

Re: per bash feststellen ob Dateityp in Verzeichnis

Beitrag von curt123 » 14.11.2021 18:03:54

Meillo hat geschrieben: ↑ zum Beitrag ↑
14.11.2021 17:17:05
Edit: heinz' Vorschlag finde ich aber lesbarer. Den wuerde ich verwenden.
Ich finde die letzten Ansätze oder Lösungen schon elegant.

Aber vielleicht kann auch noch abgeschätzt werden, ob der Abbruch per return oder break sparsamer ist.

Und ich sehe bei den anderen Versionen den möglichen Vorteil, dass Verzeichnisse nicht mit berücksichtigt werden. Und dann noch grundsätzlich, hier evtl. übertrieben, den "langweiligen" Code als evtl. gut wartbar, selbsterklärend.
Bloss sehe ich keinen Grund den Verzeichnis- und Datei-Anteil aufzutrennen. Das kann ein einziges Argument sein. Und dann gibt es auch keinen Grund die Funktion irgendewas mit ``dir'' zu nennen.
Ein separater Pfad ist m.E. flexibler und passt bei mir u.U. auch besser zu einem möglichen Anwendungsfall, wo ich verschiedene Verzeichnisse durchlaufe.
Wobei ich da auch z.B. per cd in die Verzeichnisse gehen kann, und der Pfad dann ja ähnlich einer Variable schon vorgegeben ist, dann wäre es allerdings obsolet.

Die Frage guter und stimmiger Bezeichner interessiert mich aber grundsätzlich. Ist "dir", abgesehen vom inhaltlichen Bezug, irgendwie "evil"?

Benutzeravatar
Meillo
Moderator
Beiträge: 9241
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: per bash feststellen ob Dateityp in Verzeichnis

Beitrag von Meillo » 14.11.2021 18:23:50

curt123 hat geschrieben: ↑ zum Beitrag ↑
14.11.2021 18:03:54
Und ich sehe bei den anderen Versionen den möglichen Vorteil, dass Verzeichnisse nicht mit berücksichtigt werden.
Das stimmt, aber alles Beispiele bisher waren auf Dateiendungen bezogen, so dass mir das nebensaechlich erscheint.
Bloss sehe ich keinen Grund den Verzeichnis- und Datei-Anteil aufzutrennen. Das kann ein einziges Argument sein. Und dann gibt es auch keinen Grund die Funktion irgendewas mit ``dir'' zu nennen.
Ein separater Pfad ist m.E. flexibler und passt bei mir u.U. auch besser zu einem möglichen Anwendungsfall, wo ich verschiedene Verzeichnisse durchlaufe.
Wobei ich da auch z.B. per cd in die Verzeichnisse gehen kann, und der Pfad dann ja ähnlich einer Variable schon vorgegeben ist, dann wäre es allerdings obsolet.
Du kannst doch auch so mehrere Verzeichnisse durchlaufen:

Code: Alles auswählen

for i in dir1 dir2 dir3; do
	have_files_matching "$i/*.txt"
done
Wenn du genau ein Verzeichnis und ein Dateinamenspattern uebergibst, dann sehe ich keinen Grund das aufzusplitten. Falls man es innerhalb der Funktion separat braucht, dann kann man ja mit ${1%/*} und ${1##*/} zerlegen.

Es haengt vom konkreten Anwendungsfall ab. Entscheiden wird es sich wohl an der Frage der Erweiterung auf mehrere Argumente: ob ich fuer genau ein Verzeichnis mehrere Patterns angeben wollen kann oder ob ich mehrere Pfade uebergeben wollen kann. Bzw. an der Frage, ob das Pattern auch im Verzeichnisanteil sinnvoll sein kann (was mit meiner und heinz' Variante moeglich ist).

Generell wuerde ich halt etwas, das einen kompletten Pfad (mit Globbing) darstellt, nicht in zwei Argumente teilen wollen. Das kommt mir unnatuerlich vor.
Die Frage guter und stimmiger Bezeichner interessiert mich aber grundsätzlich. Ist "dir", abgesehen vom inhaltlichen Bezug, irgendwie "evil"?
Nein, das bezog sich auf die Ausage davor: Wenn es kein separates Dir-Argument mehr gibt, dann sollte die Funktion auch nicht ``dir''-Irgendwas heissen. Fuer die Variante mit zwei Argumenten ist der Name schon passend.
Use ed once in a while!

curt123
Beiträge: 704
Registriert: 19.10.2018 12:49:35
Wohnort: NRW

Re: per bash feststellen ob Dateityp in Verzeichnis

Beitrag von curt123 » 14.11.2021 18:32:09

JTH hat geschrieben: ↑ zum Beitrag ↑
14.11.2021 17:33:42
Auch das klappt so nicht, das echo 0 muss aus der Schleife raus. Und das break ein return werden. Zumindest mit der Anforderung, aufs Muster passende Ordner ignorieren zu können. Die Funktion scheitert sonst z.B. hieran:

Code: Alles auswählen

$ mkdir -p dir dir/{aaa,bbb,ccc}.txt
$ touch dir/{ddd,eee,fff}.txt
$ is_in_dir dir "*.txt"
0
0
0
1
Danke, das Beispiel kommt mir im ersten Moment etwas wild vor, aber wenn es immer funktionieren soll kann ich das wohl schlecht zulassen ;)

Antworten