13 ответов:
вот как это сделать с операторами # и % в Bash.
$ x="/foo/fizzbuzz.bar" $ y=${x%.bar} $ echo ${y##*/} fizzbuzz
${x%.bar}также может быть${x%.*}чтобы удалить все после точки или${x%%.*}удалить все после первой точки.пример:
$ x="/foo/fizzbuzz.bar.quux" $ y=${x%.*} $ echo $y /foo/fizzbuzz.bar $ y=${x%%.*} $ echo $y /foo/fizzbuzzдокументация может быть найдена в руководство Bash. Ищите
${parameter%word}и${parameter%%word}хвостовая часть соответствующего сечения.
Pure bash, выполненный в двух отдельных операциях:
удалить путь из строки пути:
path=/foo/bar/bim/baz/file.gif file=${path##*/} #$file is now 'file.gif'удалите расширение из строки пути:
base=${file%.*} #${base} is now 'file'.
используя basename я использовал следующее Для достижения этой цели:
for file in *; do ext=${file##*.} fname=`basename $file $ext` # Do things with $fname done;это не требует априорного знания расширения файла и работает даже тогда, когда у вас есть имя файла, которое имеет точки в его имени файла (перед его расширением); это требует программы
basenameхотя, но это часть GNU coreutils, поэтому он должен поставляться с любым дистрибутивом.
Pure bash way:
~$ x="/foo/bar/fizzbuzz.bar.quux.zoom"; ~$ y=${x/\/*\//}; ~$ echo ${y/.*/}; fizzbuzzэта функциональность объясняется на man bash в разделе "расширение параметров". Не Баш способов предостаточно: awk, perl, sed и так далее.
редактировать: работает с точками в файле суффиксы и не нужно знать суффикс (расширение), но не работа с точками в имя сам по себе.
функции basename и dirname-это то, что вам нужно:
mystring=/foo/fizzbuzz.bar echo basename: $(basename $mystring) echo basename + remove .bar: $(basename $mystring .bar) echo dirname: $(dirname $mystring)выход:
basename: fizzbuzz.bar basename + remove .bar: fizzbuzz dirname: /foo
используя
basenameпредполагается, что вы знаете, что расширение файла, не так ли?и я считаю, что различные предложения регулярных выражений не справляются с именем файла, содержащим более одного "."
следующее, кажется, справляется с двойными точками. О, и имена файлов, которые содержат " / " сами (просто для удовольствия)
перефразируя Паскаля, " Извините, что этот сценарий так долго. У меня не было времени сделать его короче"
#!/usr/bin/perl $fullname = $ARGV[0]; ($path,$name) = $fullname =~ /^(.*[^\]\/)*(.*)$/; ($basename,$extension) = $name =~ /^(.*)(\.[^.]*)$/; print $basename . "\n";
Если вы не можете использовать basename, как это предлагается в других сообщениях, вы всегда можете использовать sed. Вот (уродливый) пример. Это не самый большой, но он работает путем извлечения нужной строки и замены ввода на нужную строку.
echo '/foo/fizzbuzz.bar' | sed 's|.*\/\([^\.]*\)\(\..*\)$||g'который даст вам выход
fizzbuzz
остерегайтесь предлагаемого решения perl: он удаляет все, что после первой точки.
$ echo some.file.with.dots | perl -pe 's/\..*$//;s{^.*/}{}' someесли вы хотите сделать это с Perl, это работает:
$ echo some.file.with.dots | perl -pe 's/(.*)\..*$//;s{^.*/}{}' some.file.withно если вы используете Bash, то решения с
y=${x%.*}(илиbasename "$x" .extЕсли вы знаете расширение) гораздо проще.
объединение топ-рейтинг ответ со вторым топ-рейтинг ответ, чтобы получить имя файла без полного пути:
$ x="/foo/fizzbuzz.bar.quux" $ y=(`basename ${x%%.*}`) $ echo $y fizzbuzz
базовое имя делает это, удаляет путь. Он также удалит суффикс, если он задан, и если он соответствует суффиксу файла, но вам нужно будет знать суффикс, чтобы дать команде. В противном случае вы можете использовать mv и выяснить, что новое имя должно быть каким-то другим способом.
информация, которую вы можете найти в Bash manual искать
${parameter%word}и${parameter%%word}в разделе соответствия задней части.
Comments