如何使用 sed 仅获取文件名

如何使用 sed 仅获取文件名

如何使用 sed 只获取文件名?我有这个

out_file=$(echo $in_file|sed "s/\(.*\.\).*/\1mp4/g")

但我也得到了路径/root/video.mp4,而且我想要的只是video.mp4

答案1

basename来自 GNU核心工具可以帮助您完成这项工作:

$ basename /root/video.mp4
video.mp4

如果您已经知道文件的扩展名,则可以basename使用以下语法调用basename NAME [SUFFIX]以将其删除:

$ basename /root/video.mp4 .mp4
video

或者另一种选择是使用以下命令剪切最后一个点之后的所有内容sed

$ basename /root/video.old.mp4 | sed 's/\.[^.]*$//'
video.old

答案2

最简单的解决方案是删除所有内容,直到最后出现/

echo /root/video.mp4 | sed 's/.*\///'

答案3

使用以下任一方式:

out_file="${in_file##*/}"

out_file="$(basename $in_file)"

out_file="$(echo $in_file | sed 's=.*/==')"

out_file="$(echo $in_file | awk -F"/" '{ print $NF }')"

附注您会得到相同的字符串,因为您的语句中\(.*\.\)从头到点 ( /root/video.) 都与字符串匹配,然后您手动添加.mp4与原始字符串中相同的字符串。你应该改用s=.*\([^/]*\)=\1=

更新:(第一个现已修复)

要获取唯一不带扩展名的文件名,您可以:

out_file="$(echo $in_file | sed 's=.*/==;s/\.[^.]*$/.new_ext/')"

out_file="$(echo $in_file | sed 's=\([^/]*\)\.[^./]*$=\1.new_ext=')"

out_file="$(echo $in_file | awk -F"/" '{ gsub (/\.[^/.]*$/,".new_ext",$NF);print $NF }'

答案4

POSIXly,删除目录名称和扩展名:

rootname() {
  LC_ALL=C awk -- 'BEGIN{
    for (i = 1; i < ARGC; i++) {
      file = ARGV[i]
      if (file == "")
        print ""
      else {
        sub("/*$", "", file) # remove trailing / characters if any
        if (file == "")
          print "/"
        else {
          sub(".*/", "", file) # remove dir part
          if (file ~ /[^.]\./) # has a . other than as the first character
                               # also do not consider . and .. have an extension
            sub(/\.[^.]*$/, "", file)
          print file
        }
      }
    }
  }' "$@"
}

例子:

$ rootname ~/.zshrc
.zshrc
$ rootname foo/bar/
bar
$ rootname /
/
$ rootname ""

$ rootname .foo.bar
.foo
$ rootname file.tar.gz
file.tar
$ rootname foo.d/bar
bar
$ rootname $'foo.d/\nbar.x'

bar

csh、tcsh、zsh、bash 或 vim 有:t尾巴) 和:r) 修饰符可以组合起来以:t:r获得尾巴,但请注意:

  • 在 中bash,它仅在历史扩展中可用,因此当您需要将其应用于变量的内容时没有用。
  • rootname对于极端情况值(如 )或没有扩展名的隐藏文件(如 ),您将从上面的函数/..得到~/.cshrc不同的结果。
  • 除了 in 之外zsh, withfile=/foo/bar/扩展$file:t:r为空字符串。

可以对 执行相同的操作sed,但它不会像使用 那样清晰awk

rootname() {
   printf '%s\n' "$1" | LC_ALL=C sed '
     :1
     $!{
       N; # load full input into pattern space for filenames with newlines
       b1
     }

     # handle the empty string
     /./!b

     # remove trailing slashes
     s|/*$||

     /./! {
       # handle slash
       s|^|/|
       b
     }

     s|.*/||; # remove dir part
     /[^.]\./ s/\.[^.]*$//'
}

相关内容