Untuk file dalam direktori, hanya echo nama file (tanpa jalur)

98

Bagaimana cara menggemakan hanya nama file dari file jika saya mengulang direktori dengan loop for?

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

akan menarik jalur lengkap dengan nama file. Saya hanya ingin nama file.

Mechaflash
sumber

Jawaban:

166

Jika Anda menginginkan bashsolusi asli

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

Di atas menggunakan Ekspansi Parameter yang merupakan bawaan dari shell dan tidak memerlukan panggilan ke biner eksternal sepertibasename

Namun, mungkin saya sarankan untuk menggunakan find

find /home/user -type f -printf "%f\n"
SiegeX
sumber
9
Jawaban yang bagus. Bagi mereka yang tertarik untuk mempelajari lebih lanjut tentang perluasan parameter: wiki.bash-hackers.org/syntax/pe#substring_removal
DougW
1
-printf: primer atau operator tidak diketahui => unix.stackexchange.com/a/272493/72893
Nobita
2
Pertimbangkan ${file##*/}untuk mengubah ke "${file##*/}"untuk mendukung nama file dengan spasi misalnya "Nama file saya dengan spasi.txt".
WinEunuuchs2Unix
echo "$ {file ## * /}" mengembalikan string kosong
Alessandro C
47

Gunakan saja basename:

echo `basename "$filename"`

Tanda kutip diperlukan jika $ filename berisi misalnya spasi.

Sean Bright
sumber
3
lebih baik menggunakan perluasan parameter, tidak memerlukan panggilan ke biner eksternal.
SiegeX
5
Btw, `` tidak digunakan lagi. Lebih baik menggunakan $()seperti yang dilakukan Oli
SiegeX
1
Maaf telah mengomentari jawaban lama ini, tetapi nama dasar tidak akan berfungsi dengan benar untuk file dengan spasi. Contoh: Output pwd: /test 1, basename $(pwd)keluaran: test. Diuji di OS X dan Server Ubuntu (14.04). Solusi bash asli, seperti yang direkomendasikan @SiegeX, adalah yang berhasil untuk saya.
Marko Grešak
@ MarkoGrešak Gunakan basename "$(pwd)"sebagai gantinya.
YoungFrog
@YoungFrog terima kasih atas masukannya, tapi itu sudah 9 bulan yang lalu. Juga akan lebih baik menggunakan variabel $PWDdaripada menjalankan perintah.
Marko Grešak
15

Penggunaan basename:

echo $(basename /foo/bar/stuff)
Oliver Charlesworth
sumber
Mengapa Anda menggunakan echo? basenamesudah print hasilnya. echobahkan mungkin mengacaukan hasilnya jika Anda tidak mengutip subkulit. Contoh: echo $(basename path/with\ \ spaces)salah mencetak with spaces(hanya satu spasi).
Socowi
7

Pendekatan lain adalah dengan menggunakan lssaat membaca daftar file dalam direktori untuk memberikan apa yang Anda inginkan, yaitu "hanya nama file / s". Berbeda dengan membaca path file lengkap dan kemudian mengekstrak komponen "nama file" di badan loop for.

Contoh di bawah ini yang mengikuti yang asli Anda:

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

Jika Anda menjalankan skrip di direktori yang sama dengan file, maka skrip menjadi:

for filename in $(ls)
do
  echo $filename
done;
ryan
sumber
1
lsmenyertakan dotfiles apa pun yang *biasanya tidak dilakukan ekspansi. Juga for f in $(...) ...gagal jika nama file apa pun berisi spasi kecuali Anda menyetel IFS, mungkin gagal jika nama file apa pun berisi karakter glob kecuali Anda menyetel -f / -o noglob, dan bergantung pada sistem atau shell echomungkin gagal jika nama file berupa tanda hubung + huruf atau berisi garis miring terbalik. OTOH ls -1 /path/to/dirdengan sendirinya secara andal mencetak setiap nama file pada satu baris, modulo perbedaan dotfiles.
dave_thompson_085
0

jika Anda hanya ingin nama file:

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

untuk informasi lebih lanjut tentang cutperintah lihat di sini .

josef
sumber