Для файлів у каталозі лише ім'я файлу echo (без шляху)


98

Як мені повторити лише ім’я файлу, якщо я переглядаю каталог із циклом for?

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

потягне повний шлях з назвою файлу. Я просто хочу ім’я файлу.

Відповіді:


166

Якщо вам потрібне власне bashрішення

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

Вище використовується розширення параметрів, яке є рідним для оболонки і не вимагає виклику зовнішнього двійкового файлу, такого якbasename

Однак, чи можу я запропонувати просто використовувати find

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

9
Хороша відповідь. Для тих, хто хоче
DougW

1
-printf: невідомий первинний або оператор => unix.stackexchange.com/a/272493/72893
Nobita

2
Подумайте про зміну ${file##*/}на, "${file##*/}"щоб підтримати імена файлів із пробілами, наприклад "Моє ім'я файлу з пробілами.txt".
WinEunuuchs2Unix

echo "$ {file ## * /}" повертає порожній рядок
Алессандро С

47

Просто використовуйте basename:

echo `basename "$filename"`

Лапки потрібні, якщо $ filename містить, наприклад, пробіли.


3
краще використовувати розширення параметрів, не вимагає викликів до зовнішніх бінарних файлів.
SiegeX

5
До речі, `` застаріло. Краще використовувати, $()як робив Олі
SiegeX

1
Вибачте за коментар до цієї старої відповіді, але базове ім'я не буде коректно працювати з файлами з простором. Приклад: PWD вихід: /test 1, basename $(pwd)вихід: test. Тестується на OS X та Ubuntu Server (14.04). Власне рішення bash, як рекомендував @SiegeX, саме для мене спрацювало.
Marko Grešak

@ MarkoGrešak Використовуйте basename "$(pwd)"замість цього.
YoungFrog

@YoungFrog дякую за внесок, але це було 9 місяців тому. Також було б краще використовувати змінну $PWDзамість запуску команди.
Marko Grešak

15

Використання basename:

echo $(basename /foo/bar/stuff)

Чому ви використовуєте echo? basenameвже друкує результати. echoможе навіть забруднити результат, якщо ви не цитуєте передплату. Приклад: echo $(basename path/with\ \ spaces)неправильно друкує with spaces(лише один пробіл).
Socowi

7

Іншим підходом є використання lsпід час читання списку файлів у каталозі, щоб дати вам те, що ви хочете, тобто "просто ім'я / файли файлів". На відміну від читання повного шляху до файлу, а потім вилучення компонента "ім'я файлу" в тілі циклу for.

Приклад нижче, який слідує за вашим оригіналом:

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

Якщо ви запускаєте сценарій в тому ж каталозі, що і файли, він просто стає:

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

1
lsвключає будь-які крапкові файли, де *розширення, як правило, немає. Також for f in $(...) ...не вдається, якщо будь-яке ім'я файлу містить пробіл, якщо ви не встановили IFS, може бути невдалим, якщо будь-яке ім'я файлу містить глобальну таблицю, якщо ви не встановите -f / -o noglob, і залежно від системи або оболонки echoможе вийти з ладу, якщо будь-яке ім'я файлу є дефісом + літерою або містить зворотну косу рису. OTOH просто ls -1 /path/to/dirсам по собі надійно друкує кожне ім'я файлу в рядку, за модулем різниці точкових файлів.
dave_thompson_085

0

якщо ви хочете лише ім'я файлу:

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

для отримання додаткової інформації про cutкоманду дивіться тут .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.