Für Dateien im Verzeichnis nur Echo-Dateiname (kein Pfad)


98

Wie gehe ich vor, um nur den Dateinamen einer Datei wiederzugeben, wenn ich ein Verzeichnis mit einer for-Schleife iteriere?

for filename in /home/user/*
do
  echo $filename
done;

zieht den vollständigen Pfad mit dem Dateinamen. Ich möchte nur den Dateinamen.

Antworten:


166

Wenn Sie eine native bashLösung wünschen

for file in /home/user/*; do
  echo "${file##*/}"
done

Das obige verwendet die Parametererweiterung, die der Shell eigen ist und keinen Aufruf einer externen Binärdatei wie zbasename

Könnte ich jedoch vorschlagen, nur zu verwenden find

find /home/user -type f -printf "%f\n"

9
Gute Antwort. Für diejenigen, die mehr über die Parametererweiterung erfahren
möchten

1
-printf: unbekannter Primär- oder Operator => unix.stackexchange.com/a/272493/72893
Nobita

2
Ziehen Sie in Betracht, ${file##*/}zu "${file##*/}"zu wechseln , um Dateinamen mit Leerzeichen zu unterstützen, z. B. "Mein Dateiname mit Leerzeichen.txt".
WinEunuuchs2Unix

echo "$ {file ## * /}" gibt eine leere Zeichenfolge zurück
Alessandro C

47

Verwenden Sie einfach basename:

echo `basename "$filename"`

Die Anführungszeichen werden benötigt, wenn $ filename zB Leerzeichen enthält.


3
Besser die Parametererweiterung zu verwenden, erfordert keine Aufrufe von externen Binärdateien.
SiegeX

5
Übrigens ist `` veraltet. Besser zu verwenden $()wie Oli
SiegeX

1
Es tut uns leid, dass Sie diese alte Antwort kommentiert haben, aber der Basisname funktioniert bei Dateien mit Speicherplatz nicht richtig. Beispiel: pwd output : /test 1, basename $(pwd)output : test. Getestet unter OS X und Ubuntu Server (14.04). Native Bash-Lösung, wie von @SiegeX empfohlen, hat bei mir funktioniert.
Marko Grešak

@ MarkoGrešak Verwenden Sie basename "$(pwd)"stattdessen.
YoungFrog

@YoungFrog danke für die Eingabe, aber das war vor 9 Monaten. Es ist auch besser, die Variable zu $PWDverwenden, als den Befehl auszuführen.
Marko Grešak

15

Verwendung basename:

echo $(basename /foo/bar/stuff)

Warum benutzt du echo? basenamedruckt bereits die Ergebnisse. echokann das Ergebnis sogar entstellen, wenn Sie die Unterschale nicht zitieren. Beispiel: echo $(basename path/with\ \ spaces)Druckt falsch with spaces(nur ein Leerzeichen).
Socowi

7

Ein anderer Ansatz ist das lsLesen der Dateiliste in einem Verzeichnis, um Ihnen das zu geben, was Sie möchten, dh "nur den / die Dateinamen". Im Gegensatz zum Lesen des vollständigen Dateipfads und anschließenden Extrahieren der Komponente "Dateiname" im Hauptteil der for-Schleife.

Beispiel unten, das Ihrem Original folgt:

for filename in $(ls /home/user/)
do
  echo $filename
done;

Wenn Sie das Skript im selben Verzeichnis wie die Dateien ausführen, wird es einfach zu:

for filename in $(ls)
do
  echo $filename
done;

1
lsEnthält alle Punktedateien, bei denen die *Erweiterung normalerweise nicht erfolgt. for f in $(...) ...Schlägt auch fehl, wenn ein Dateiname Leerzeichen enthält, es sei denn, Sie setzen IFS, kann fehlschlagen, wenn ein Dateiname ein glob-Zeichen enthält, es sei denn, Sie setzen -f / -o noglob, und je nach System oder Shell echokann dies fehlschlagen, wenn ein Dateiname Bindestrich + Buchstabe ist oder Backslash enthält. OTOH ls -1 /path/to/dirdruckt jeden Dateinamen für sich allein zuverlässig in eine Zeile, modulo den Unterschied zwischen den Punktedateien.
Dave_thompson_085

0

Wenn Sie nur Dateinamen möchten:

for file in /home/user/*; do       
  f=$(echo "${file##*/}");
  filename=$(echo $f| cut  -d'.' -f 1); #file has extension, it return only filename
  echo $filename
done

Weitere Informationen zum cutBefehl finden Sie hier .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.