2013-09-17 3 views
11

В bash Я пытаюсь сделать glob список файлов из каталога, которые будут представлены в качестве входных данных для программы. Однако я также хотел бы предоставить этой программе список имен файловBash извлечение файла basename из длинного пути

files="/very/long/path/to/various/files/*.file" 

Так что я мог бы использовать его так.

prompt> program -files $files -names $namelist 

Если glob дает мне:

/very/long/path/to/various/files/AA.file /very/long/path/to/various/files/BB.file /very/long/path/to/various/files/CC.file /very/long/path/to/various/files/DD.file /very/long/path/to/various/files/ZZ.file 

Я хотел бы получить список AA BB CC DD ZZ кормить мою программу без длинного имени пути и расширения файла. Однако я понятия не имею, как начать там! Любой намек высоко ценится!

ответ

24

Лучше использовать массив для хранения имен файлов. Строковая переменная не обрабатывает имена файлов, которые содержат пробелы.

Кроме того, вам не нужно использовать команду basename. Вместо этого используйте встроенную строчную манипуляцию bash.

Попробуйте это:

files=(/very/long/path/to/various/files/*.file) 
for file in "${files[@]}" 
do 
    filename="${file##*/}" 
    filenameWithoutExtension="${filename%.*}" 
    echo "$filenameWithoutExtension" 
done 
+2

+1 для упоминания '$ {file ## * /}' вместо вызова 'basename' – jbh

+0

не могли бы вы дать мне ссылку, откуда я могу прочитать все эти форматы соответствия строк ... –

+2

Можете ли вы хотя бы объяснить, почему один не следует использовать basename? И что на самом деле делал/сопоставлял этот шаблон манипуляции с строкой? –

6

Решение с basename для вашего вопроса

for file in $files 
do 
    file_name=$(basename $file) 
    file_name_witout_ext=${file_name%.file} 
done 

редактировать (общий способ извлечь имя файла без (одного) расширения)

for file in $files 
do 
    file_name=$(basename $file) 
    file_name_witout_ext=${file_name%.*} 
done 

Другое дело, что может случиться, чтобы иметь имя файла как " archive.tar.gz». В этом случае у вас будет два (или несколько расширений). Затем вы можете использовать оператора более greddy

for file in $files 
do 
    file_name=$(basename $file) 
    file_name_witout_ext=${file_name%%.*} 
done 
+0

+1 Вы можете быть более общий с использованием 'filename_without_extension =" $ {filename%. *} "', взятый из http://stackoverflow.com/a/965072/1983854 – fedorqui

+0

excat fedorqui , это может быть хорошо. Я просто придерживаюсь параметров ОП. – jbh

2

Это проще так:

files=(/very/long/path/to/various/files/*.file) 
names=("${files[@]##*/}") names=("${names[@]%.*}") 
progname -files "${files[@]}" -names "${names[@]}" 

Или, если вы могли бы передать их только в качестве единственного аргумента:

progname -files "${files[*]}" -names "${names[*]}" 
Смежные вопросы