去掉文件基名,保留目录部分

去掉文件基名,保留目录部分

我有一个看起来像这样的字符串

dir/subdir/othersubdir/file.txt

但它也可以看起来像

dir/file.txt

或者

dir/subdir/file.txt

现在,我正在制作一个脚本,$P其中目录的完整路径file.txt是。

现在我用这个

sed 's/\/.*txt//g'

替换以 txt 结尾且在/.当有类似的东西时,这很好用dir/file.txt,但不是我的其他例子。我该如何修复才能使其符合我想要的?

我不想匹配之前的任何子目录.*txt。我只想删除文件基本名称。

答案1

如果您不坚持使用sed那么您可以考虑使用dirname

S="dir/subdir/othersubdir/file.txt"
P=$(dirname $S)
echo $P
dir/subdir/othersubdir

S="dir/file.txt"
P=$(dirname $S)
echo $P
dir

答案2

这是sed命令:

$ P="dir/subdir/othersubdir/file.txt"
$ sed -r 's/^(.*)\/.*\.txt$/\1/' <<< $P
dir/subdir/othersubdir

在上面的命令中,我们从以结尾的变量开头sed捕获任何内容,它被称为捕获组,并作为其贝克引用,因为在它周围使用了一对括号,然后在 sed 命令的替换部分中,我们仅打印捕获的组使用其反向引用。.*^P$/*.txt\1(.*)

答案3

如果你使用的zsh生活更简单,只需使用:h修饰符:

$ var='dir/subdir/othersubdir/file.txt'
$ echo "$var:h"
dir/subdir/othersubdir

答案4

使用(以前称为 Perl_6)

~$ raku -ne 'put IO::Spec::Unix.splitpath($_).[1];'    file.txt

#OR(在 Unix 上)

~$ raku -ne 'put .IO.dirname;'    file.txt

Raku 是 Perl 家族的一种编程语言。上面的第一个代码示例采用文件路径并将它们视为IO对象,其中有四个主要类(Unix、Windows、Cygwin 和 QNX)。因为您的文件由 Unix 路径组成,所以IO::Spec::Unix调用该方法来正确理解路径分隔符等(请注意,这些单独的函数允许您例如在 Unix 机器上操作 Windows 路径)。然后splitpath将路径分为三部分:卷、路径和文件名(索引.[1]为您提供文件名)。

在 Unix 上,此代码在第二个示例中简化为put .IO.dirname;.

输入示例:

dir/subdir/othersubdir/file.txt
dir/subdir/file.txt
dir/file.txt

示例输出:

dir/subdir/othersubdir
dir/subdir
dir

https://docs.raku.org/type/IO/Spec/Unix
https://docs.raku.org/routine/dirname
https://raku.org

相关内容