GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Testen, ob Dateien mit einem Muster übereinstimmen, um ein Skript auszuführen?

Ich versuche, einen if zu schreiben -Anweisung, um zu testen, ob es Dateien gibt, die einem bestimmten Muster entsprechen. Wenn sich in einem Verzeichnis eine Textdatei befindet, sollte ein bestimmtes Skript ausgeführt werden.

Mein Code derzeit:

if [ -f /*.txt ]; then ./script fi

Bitte geben Sie einige Ideen; Ich möchte das Skript nur ausführen, wenn es eine .txt gibt im Verzeichnis.

Akzeptierte Antwort:

[ -f /*.txt ]

würde nur dann true zurückgeben, wenn eins vorhanden ist (und nur eine) nicht versteckte Datei in / dessen Name auf .txt endet und ob diese Datei eine reguläre Datei oder ein Symlink zu einer regulären Datei ist.

Das liegt daran, dass Wildcards von der Shell erweitert werden, bevor sie an den Befehl übergeben werden (hier [ ).

Also, wenn es eine /a.txt gibt und /b.txt , [ Es werden 5 Argumente übergeben:[ , -f , /a.txt , /b.txt und ] . [ würde dann das -f beanstanden hat zu viele Argumente.

Wenn Sie überprüfen möchten, ob die *.txt Muster wird in der bash auf mindestens eine nicht versteckte Datei (regulär oder nicht) erweitert Schale:

shopt -s nullglob
set -- *.txt
if [ "$#" -gt 0 ]; then
  ./script "[email protected]" # call script with that list of files.
fi
# Or with bash arrays so you can keep the arguments:
files=( *.txt )
# apply C-style boolean on member count
(( ${#files[@]} )) && ./script "${files[@]}"

shopt -s nullglob ist bash spezifisch (shopt ist nullglob kommt eigentlich von zsh ), sondern Shells wie ksh93 , zsh , yash , tcsh äquivalente Anweisungen haben.

Mit zsh , der Test für Gibt es Dateien, die einem Muster entsprechen kann mit einer anonymen Funktion und dem N geschrieben werden (für nullglob ) und Y1 (um nach dem ersten Fund zu stoppen) Glob Qualifier:

if ()(($#)) *.txt(NY1); then
  do-something
fi

Beachten Sie, dass diese Dateien durch Lesen des Inhalts des Verzeichnisses gefunden werden. Es versucht überhaupt nicht, auf diese Dateien zuzugreifen, was es effizienter macht als Lösungen, die Befehle wie ls aufrufen oder stat auf dieser von der Shell berechneten Liste von Dateien.

Das standardmäßige sh Äquivalent wäre:

set -- [*].txt *.txt
case "$1$2" in
  ('[*].txt*.txt') ;;
  (*) shift; script "[email protected]"
esac

Das Problem ist, dass bei Bourne- oder POSIX-Shells ein Muster, das nicht übereinstimmt, auf sich selbst erweitert wird. Also wenn *.txt erweitert sich zu *.txt , Sie wissen nicht, ob es daran liegt, dass es keine .txt gibt Datei im Verzeichnis oder weil es eine Datei namens *.txt gibt . Mit [*].txt *.txt erlaubt, zwischen den beiden zu unterscheiden.

Wenn Sie nun überprüfen möchten, ob die *.txt stimmt mit mindestens einem regulären überein Datei oder symbolischer Link zu einer regulären Datei (wie Ihr [ -f *.txt ] schlägt vor, was Sie tun möchten), oder dass alle Dateien, die mit *.txt übereinstimmen, angezeigt werden sind normal Dateien (nach Symlink-Auflösung), das ist wieder eine andere Sache.

Verwandte:Wie generiert man ein Skript zum Erstellen von Tabellen ohne Primär- und Fremdschlüssel in Oracle?

Mit zsh :

if ()(($#)) *.txt(NY1-.); then
  echo "there is at least one regular .txt file"
fi
if ()(($#)) *.txt(NY1^-.); then
  echo "there is at least one non-regular .txt files"
fi

(Entfernen Sie den - wenn Sie den Test vor der Symlink-Auflösung durchführen möchten, betrachten Sie Symlinks als nicht reguläre Dateien, unabhängig davon, ob sie auf reguläre Dateien verweisen oder nicht).


Linux
  1. Fügen Sie nach Musterübereinstimmungen mithilfe von Linux-Shell-Skript mehrere Datenzeilen in eine Datei ein

  2. Ist es möglich herauszufinden, welches Programm oder Skript eine bestimmte Datei erstellt hat?

  3. Cat-Dateien mit Verzeichnis?

  4. Bash-Skript-Musterabgleich

  5. So übergeben Sie mehrere Argumente zur Ausführung mit dem .sh-Skript

Binärdateien unter Linux ausführen

Älteste Datei finden und löschen, wenn mehr als X Dateien in einem Verzeichnis in Linux vorhanden sind

Warum sind .so-Dateien ausführbar?

Finden Sie eine Datei, die mit einem bestimmten Muster übereinstimmt, und geben Sie diesen Dateinamen als Wert an eine Variable im Shell-Skript?

So finden Sie heraus, ob Dateien in einem Ordner vorhanden sind, und beenden ihn entsprechend (in KSH)

Wie verwende ich den Befehl find, um Dateien zu löschen, die einem Muster entsprechen?