如何在bash shell中链接文件名修饰符?

Jul*_*ann 8 bash modifier chain

我理解修饰符### %%%,但我无法弄清楚它是否可以在tcsh中将它们链接在一起.

tcsh中的示例

set f = /foo/bar/myfile.0076.jpg
echo $f:r:e
--> 0076

echo $f:h:t
--> bar
Run Code Online (Sandbox Code Playgroud)

在bash中,我想知道如何做以下事情:

echo ${f%.*#*.}
Run Code Online (Sandbox Code Playgroud)

在一条线上.

我的目标是能够在命令行上根据需要以各种方式操作文件名.我不是要为一个特定的案例编写脚本.因此,如果有一种方法可以链接这些修饰符,或者可能有另一种方式,那么我很想知道.谢谢

Sie*_*geX 5

在bash中,您可以嵌套参数扩展,但只能在单词部分中有效${parameter#word}.

例如:

$ var="foo.bar.baz"; echo ${var%.*}
foo.bar
$ var="foo.bar.baz"; echo ${var#foo.bar}
.baz
$ var="foo.bar.baz"; echo ${var#${var%.*}}
.baz
Run Code Online (Sandbox Code Playgroud)

要使用纯参数扩展来执行您想要的操作,您需要具有如下的临时变量:

$ var="/foo/bar/myfile.0076.jpg"; tmp=${var#*.}; out=${tmp%.*}; echo $out
0076
Run Code Online (Sandbox Code Playgroud)

但是,如果您愿意使用set内置,那么您可以通过一些巧妙地使用搜索/替换参数扩展来实际访问所有字段,如下所示:

$ var="/foo/bar/myfile.0076.jpg"; set -- ${var//[.\/]/ }; echo $4
0076
Run Code Online (Sandbox Code Playgroud)


Jul*_*ann 1

我找到了一个非常接近 tcsh 文件名修饰符的简单性的解决方案。我写了4个函数并将它们放在.bashrc中。

e() # the extension
E() # everything but the extension
t() # the tail - i.e. everything after the last /
T() # everything but the tail (head)
Run Code Online (Sandbox Code Playgroud)

定义在最后。

这些函数可以接受如下参数:

f=foo/bar/my_image_file.0076.jpg
e $f
--> jpg
E $f
--> foo/bar/my_image_file.0076
Run Code Online (Sandbox Code Playgroud)

或者接受来自管道的输入,这是我真正想要的 tcsh 功能:

echo $f|E|e
--> 0076
Run Code Online (Sandbox Code Playgroud)

或者当然是组合:

T $f|t
--> bar
Run Code Online (Sandbox Code Playgroud)

我刚刚意识到它会通过管道接受许多文件:

ls foo/bar/
--> my_image_file.0075.jpg  my_image_file.0076.jpg
ls foo/bar/ |E|e
--> 0075
--> 0076
Run Code Online (Sandbox Code Playgroud)

定义:

#If there are no args, then assume input comes from a pipe.

function e(){
    if [ $# -ne 0 ]; then
        echo ${1##*.}  
    else
        while read data; do
            echo  ${data##*.}   ; 
        done
    fi
}

function E(){
    if [ $# -ne 0 ]; then
        echo ${1%.*} 
    else
        while read data; do
            echo ${data%.*}
        done
    fi
}

function t(){
    if [ $# -ne 0 ]; then
        echo ${1##*/}  
    else
        while read data; do
            echo  ${data##*/}   ; 
        done
    fi
}

function T(){
    if [ $# -ne 0 ]; then
        echo ${1%/*} 
    else
        while read data; do
            echo ${data%/*}
        done
    fi
}
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,使用 `function` 关键字会使您的代码比没有它时的可移植性更差 - 只要 `T() {` 前面没有 `function` 就是一个 POSIX 兼容的函数声明(的开头),并且可以工作即使用灰烬或破折号。 (2认同)