【问题标题】:Remove first directory components from path of file从文件路径中删除第一个目录组件
【发布时间】:2011-07-15 18:43:03
【问题描述】:

我需要从 Bash 中的变量中删除一个目录(最左侧)。我找到了如何删除所有路径或使用dirname 和其他路径的方法,但它正在删除右侧的所有或一个路径组件;这对我没有帮助。所以你对我需要什么有更好的理解,我会写一个例子:

我有a/project/hello.ca/project/docs/README,...我想删除那个a/,所以在执行一些命令后,我将拥有project/hello.cproject/docs/README,...

【问题讨论】:

    标签: bash shell text-processing


    【解决方案1】:

    您可以使用以下任何一种:

    x=a/b/c/d
    y=a/
    echo ${x#a/}
    echo ${x#$y}
    echo ${x#*/}
    

    所有三个回显命令都产生b/c/d;当然,您可以以任何您选择的方式使用该值。

    当您知道编写脚本时需要删除的名称时,第一个是合适的。

    当您有一个包含您需要删除的前缀的变量时,第二个是合适的(次要变体:y=a; echo ${x#$y/})。

    第三个是最通用的 - 它删除了直到第一个斜杠的任意前缀。当我在 MacOS X 10.6.6 上使用 bash(版本 3.2)测试 * 时,我惊喜地发现它的工作非贪婪 - 我将把它归结为过多的 Perl 和正则表达式工作(因为,仔细想想,shell 中的* 不包括斜线)。

    【讨论】:

    • * 可以在此上下文中包含斜杠。 a='abc/def.ghi'; echo ${a#*.} 输出“ghi” 但是你是对的,当你使用 # 时它并不贪婪,## 让它变得贪婪。
    • ### 运算符实际上是做什么的?
    • @Pitt: RTFM?哈希运算符(以“h”开头)从变量的“头”中删除内容。 # 之后的模式与变量的值匹配,匹配的位(如果有)被删除。使用##,将删除最长的匹配项。百分比运算符(尾部带有 't')是 # 的补码,用于从变量尾部删除内容。例如,% 可用于从文件名中删除后缀。
    • @JonathanLeffler:干杯 :) 又学到了更多关于 bash 的知识!
    • 将它应用到数组时,我惊讶地发现 "${array[@]/#*\/}" 是贪婪的,而 "${array[@]/##* \/}" 什么都不做。
    【解决方案2】:
    echo a/project/hello.c | cut -d'/' -f2-
    

    【讨论】:

    • 我喜欢这个,简单易概括。我有一个类似的问题,我需要让它工作的只是将 -f2- 中的数字增加到 -f5- 对于我的情况。对其他解决方案中给出的正则表达式做同样的事情会困难得多。
    【解决方案3】:
    echo "a/project/hello.c" | sed 's,^[^/]*/,,'
    

    【讨论】:

      【解决方案4】:

      man expr

      expr "foo/bar/baz" : '[^/]*/\(.*\)' 会做你想做的事。

      【讨论】:

        【解决方案5】:

        您可以通过管道连接到 xargs 并进行新的替换

        我如何使用它将 ts-src 下目录中的所有文件从 ts 重命名为 js 和 tsx 重命名为 jsx 到相同的子目录。

        find ts-src/ -type f -not -name "*.tsx" -not -name "*.ts" \
          -exec bash -c 'echo "${0##*/}" "${0##ts-src/}" "$0"' {} \; | \
            xargs -l bash -c 'echo mkdir -p "src/${1%$0}" && echo cp "$2" "src/$0"'
        

        【讨论】:

          【解决方案6】:

          上面的例子都没有解决我的问题。我希望能够通过更改 $PATH 值来切换 java 版本。谷歌搜索后找不到足够的答案,我在下面编织了自己的解决方案。

          这是我的 .bashrc 中的一段摘录:

          jv8() {
              export JAVA_HOME=/opt/jdk1.8.0_121
              y=$(echo $PATH | tr ':' '\n' |sed '/\/opt\/jdk/d' | tr '\n' ':')
              export PATH=$JAVA_HOME/bin:$y
          }
          
          jv6() {
              export JAVA_HOME=/opt/jdk1.6.0_45
              y=$(echo $PATH | tr ':' '\n' |sed '/\/opt\/jdk/d' | tr '\n' ':')
              export PATH=$JAVA_HOME/bin:$y
          }
          

          所以,在我的 bash shell 中,我可以通过以下方式简单地切换:

          $> jv6
          java -version
          java version "1.6.0_45"
          Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
          Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode)
          $> jv8
          java -version
          java version "1.8.0_121"
          Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
          Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
          

          【讨论】:

            猜你喜欢
            • 2021-01-30
            • 1970-01-01
            • 1970-01-01
            • 2014-12-30
            • 2013-11-20
            • 2016-07-04
            • 1970-01-01
            • 1970-01-01
            • 2014-12-11
            相关资源
            最近更新 更多