Wie lässt sich das richtige Ende eines Pfades ermitteln?

Wie lässt sich das richtige Ende eines Pfades ermitteln?

Ich habe eine Shell-Variable, die diesen Pfad enthält

/usr/share/man/man1/bitmap.1

Es KÖNNTE eine Datei mit dem Namen bitmap.1 geben, es könnte aber auch bitmap.1.z, bitmap.1.gz oder bitmap.1.Z heißen.

Jetzt möchte ich die echte Datei an eine Funktion übergeben und gleichzeitig die richtige Datei auflösen, wie

function process {
    # do something
}

path="/usr/share/man/man1/bitmap.1"

process ${path}.(z|Z|gz) # here the shell shall resolve the real filename

Gibt es eine Möglichkeit, dies elegant zu tun, oder muss ich testen, ob bitmap.1, bitmap.1.z usw. beendet werden und diese Datei dann an die Funktion übergeben???


Ich habe vergessen zu erwähnen, dass ich auf die Bourne-Shell beschränkt bin und daher keine Brace-Erweiterung zur Hand habe -,-.

Antwort1

Sie können das Globbing weiterhin in Bourne Shell durchführen

for f in ${given-path}*; do
process $f
done

Es ist eine gute Idee, so viele Shell-Skripte wie möglich auf die Bourne-Shell-Syntax zu beschränken. Dadurch wird die Portabilität maximiert. In vielen Fällen verbessert sich dadurch auch die Geschwindigkeit.

Antwort2

Wenn Sie die Liste der möglichen Erweiterungen kennen, können Sie Folgendes tun:

process ${path}{,.Z,.Z,.gz}

Antwort3

Ich glaube, Christian ist auf dem richtigen Weg. Wenn Sie sich zumindest eines Teils Ihres Pfads sicher sind, werden mit dem in Bash integrierten Globbing alle Dateien angezeigt, die Ihrem Muster entsprechen.

Beispielsweise habe ich in meiner .profile-Datei eine Funktion, die ich häufig verwende, um gzippte und reine Text-Protokolldateien zu caten:

function mscat {
  is_gzip="\.gz$"

  for file in $@; do
    if [[ "$file" =~ $is_gzip ]]; then
      zcat $file
    else
      cat $file
    fi
  done
}

Das würde ich so nennen:

mscat /var/log/ncftpd/sess.2010*

Da Globbing mehr als ein Ergebnis liefern kann, sollte Ihre Funktion „Prozess“ in der Lage sein, auf mehrere Argumente zu reagieren. In meinem Beispiel können Sie sehen, wie ich das mache, indem ich über jedes Argument in $@ iteriere.

Antwort4

Wenn Sie nur eine Datei haben, können Sie Bash-Globbing verwendenprocess ${path}*

verwandte Informationen