unix 在bash中提取不带路径和扩展名的文件basename [duplicate]

ukqbszuj  于 2023-08-04  发布在  Unix
关注(0)|答案(9)|浏览(142)

此问题在此处已有答案

Extract filename and extension in Bash(38个答案)
6年前关闭。
给定文件名如下:

/the/path/foo.txt
bar.txt

字符串
我希望得到:

foo
bar


为什么这个不管用?

#!/bin/bash

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


怎么做才是正确的呢?

lp0sw83n

lp0sw83n1#

您不必调用外部basename命令。相反,您可以使用以下命令:

$ s=/the/path/foo.txt
$ echo "${s##*/}"
foo.txt
$ s=${s##*/}
$ echo "${s%.txt}"
foo
$ echo "${s%.*}"
foo

字符串
请注意,此解决方案应该在所有最近的(post 2004POSIX 兼容shell中工作(例如bashdashksh等)。
来源:Shell Command Language 2.6.2参数扩展
更多关于bash String Manipulations:http://tldp.org/LDP/LG/issue18/bash.html

fwzugrvs

fwzugrvs2#

basename命令有两种不同的调用;在一种情况下,你只指定路径,在这种情况下,它会给你最后一个组件,而在另一种情况下,你也会给一个后缀,它会删除。因此,您可以通过使用basename的第二次调用来简化示例代码。另外,要注意正确引用:

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

字符串

puruo6ea

puruo6ea3#

basename和cut的组合可以很好地工作,即使是像.tar.gz这样的双结尾:

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

字符串
如果这个解决方案需要比Bash参数扩展更少的算术能力,那将是有趣的。

5uzkadbs

5uzkadbs4#

以下是oneliners:
1.第一个月

  1. $(basename "${s}" ".${s##*.}")
    我需要这个,就像bongbang和w4etwetwtwtwet问的一样。
    示例如下:
$ s=/the/path/foo.txt
$ echo "$(basename "${s%.*}")"
foo
$ echo "$(basename "${s}" ".${s##*.}")"
foo

字符串

axzmvihb

axzmvihb5#

bash,没有basename,没有变量杂耍。设置一个字符串和echo

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

字符串
输出量:

foo


注意:bashextglob选项必须为“on”,(Ubuntu 默认设置extglob为“on”),如果不是,请执行:

shopt -s extglob


走进${p//+(*\/|.*)}

  1. ${p--以 $p 开头。
  2. //替换以下模式的每个示例。
  3. +(匹配括号中的 * 模式列表 * 中的 * 一个或多个 ,( 即 * 直到下面的项目#7)。
    1.* 第一 * 图案:*\/匹配文字“/“char之前的任何内容。
    1.模式分隔符|,在这种情况下,它的作用类似于logical OR
    1.* 第二 * 图案:.*匹配文字“.”之后的任何内容-也就是说,在bash中,“.”只是一个句点字符,而 * 不是 * a regex dot
  4. ) end pattern list.
  5. }结束参数展开。对于字符串替换,通常会有另一个/,后跟一个替换字符串。但由于没有/,匹配的模式被替换为空;这将删除匹配。
    相关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

fzsnzjdm

fzsnzjdm6#

下面是另一种(更复杂)获取文件名或扩展名的方法,首先使用rev命令反转文件路径,从第一个.开始剪切,然后再次反转文件路径,如下所示:

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

字符串

sg24os4d

sg24os4d7#

如果你想玩好Windows文件路径(在Cygwin下),你也可以试试这个:

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

字符串
这将说明在Windows上使用BaSH时的反斜杠分隔符。

tkclm6bt

tkclm6bt8#

只是一个替代方案,我想出了提取一个扩展,使用帖子在这个线程与我自己的小知识库,这是我更熟悉。

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

字符串
注:请对我的报价使用建议;它对我很有效,但我可能在它们的正确使用上遗漏了一些东西(我可能用得太多了)。

相关问题