如何使用 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/\.[^.]*$//'
}