Извлечение имени файла без пути и расширения в bash [дубликат]



этот вопрос уже есть ответ здесь:




  • Извлечь имя файла и расширение в Bash

    35 ответов



дали имена файлов, как это:



/the/path/foo.txt
bar.txt


Я надеюсь получить:



foo
bar


почему это не сработает?



#!/bin/bash

fullfile=
fname=$(basename $fullfile)
fbname=${fname%.*}
echo $fbname


Как правильно это сделать?

1087   9  

9 ответов:

вы не должны вызывать внешний

на basename команда имеет два разных вызова; в одном вы указываете только путь, и в этом случае он дает вам последний компонент, а в другом вы также даете суффикс, который он удалит. Таким образом, вы можете упростить свой пример кода, используя второй вызов basename. Кроме того, будьте осторожны, чтобы правильно цитировать вещи:

fbname=$(basename "" .txt)
echo "$fbname"

комбинация basename и cut отлично работает, даже в случае двойного окончания, например .tar.gz:

fbname=$(basename "$fullfile" | cut -d. -f1)

было бы интересно, если это решение требует меньше арифметической мощности, чем расширение параметра Bash.

чисто bash, нет basename, без переменной жонглирования. Установите строку и echo:

s=/the/path/foo.txt
echo ${s//+(*\/|.*)}

выход:

foo

Примечание:bashextglob опция должна быть "on", (on Ubuntu он "включен" по умолчанию), если это не так, сделайте:

shopt -s extglob

пешком через ${s//+(*\/|.*)}:

  1. ${s -- начинаются с $s.
  2. // заменить каждый экземпляр узор.
  3. +( матч один или несколько на список шаблон в скобках.
  4. *\/ соответствует что-нибудь до /. (1-й образец)
  5. | или. (разделитель шаблонов.)
  6. .* соответствует что-нибудь после .. (2-й образец)
  7. ) конец список шаблон.
  8. } расширение конечного параметра -- так как нет / (который будет предшествовать замене строки), совпадающие шаблоны удаляются.

соответствующей man bash справочная информация:

  1. замена шаблона:
  ${parameter/pattern/string}
          Pattern substitution.  The pattern is expanded to produce a pat‐
          tern just as in pathname expansion.  Parameter is  expanded  and
          the  longest match of pattern against its value is replaced with
          string.  If pattern begins with /, all matches  of  pattern  are
          replaced   with  string.   Normally  only  the  first  match  is
          replaced.  If pattern begins with #, it must match at the begin‐
          ning of the expanded value of parameter.  If pattern begins with
          %, it must match at the end of the expanded value of  parameter.
          If string is null, matches of pattern are deleted and the / fol‐
          lowing pattern may be omitted.  If parameter is @ or *, the sub‐
          stitution  operation  is applied to each positional parameter in
          turn, and the expansion is the resultant list.  If parameter  is
          an  array  variable  subscripted  with  @ or *, the substitution
          operation is applied to each member of the array  in  turn,  and
          the expansion is the resultant list.
  1. расширенный поиск по шаблону:
  If the extglob shell option is enabled using the shopt builtin, several
   extended  pattern  matching operators are recognized.  In the following
   description, a pattern-list is a list of one or more patterns separated
   by a |.  Composite patterns may be formed using one or more of the fol‐
   lowing sub-patterns:

          ?(pattern-list)
                 Matches zero or one occurrence of the given patterns
          *(pattern-list)
                 Matches zero or more occurrences of the given patterns
          +(pattern-list)
                 Matches one or more occurrences of the given patterns
          @(pattern-list)
                 Matches one of the given patterns
          !(pattern-list)
                 Matches anything except one of the given patterns

вот oneliners:

  1. $(basename ${s%.*})
  2. $(basename ${s} .${s##*.})

я нуждался в этом, так же, как просил bongbang и w4etwetewtwet.

вот еще один (более сложный) способ получения имени файла или расширения, сначала используйте rev команда инвертировать путь к файлу, вырезать из первого . а затем снова инвертировать путь к файлу, например:

filename=`rev <<< "" | cut -d"." -f2- | rev`
fileext=`rev <<< "" | cut -d"." -f1 | rev`

Если вы хотите играть хорошо с пути к файлам Windows (под Cygwin) вы также можете попробовать это:

fname=${fullfile##*[/|\]}

Это будет учитывать разделители обратной косой черты при использовании BaSH на Windows.

просто альтернатива, которую я придумал, чтобы извлечь расширение, используя сообщения в этой теме с моей собственной небольшой базой знаний, которая была мне более знакома.

ext="$(rev <<< "$(cut -f "1" -d "." <<< "$(rev <<< "file.docx")")")"

Примечание: пожалуйста, сообщите о моем использовании кавычек; это сработало для меня, но я мог бы упустить что-то при их правильном использовании (я, вероятно, использую слишком много).

используйте команду basename. Его manpage находится здесь:http://unixhelp.ed.ac.uk/CGI/man-cgi?basename

Comments

    Ничего не найдено.