简体   繁体   English

Bash一线式隔离目录名称

[英]Bash one-liner for isolating directory name

In Bash, v.4.3.11(1) I have this sample code: 在Bash v.4.3.11(1)中,我有以下示例代码:

#!/bin/bash

dir=("/home/user/Documents/" "/home/user/Music/" "/home/user/Videos/" \
"/home/user/Photos/")

baseDir="/home/user/"

for i in "${!dir[@]}"
do
    niceName=${dir[$i]#"$baseDir"}  # removes baseDir from front part
    printf "%s\n" "${niceName%"/"}"  # also removes trailing slash from end
done

Is there a way to combine the two commands in one and have only the printf within the for loop? 有没有一种方法可以将两个命令合而为一,并且仅将printf包含在for循环中? (preferably without resorting to awk or sed, but ok, if inevitable). (最好不要诉诸awk或sed,但如果可以的话,可以)。

I have tried various combinations but I am ending up with "bad substitution" errors. 我尝试了各种组合,但最终出现“替代不良”错误。 For example, printf "%s\\n" "${niceName=${dir[$i]#"$baseDir"%"/"}" is not working for me. 例如, printf "%s\\n" "${niceName=${dir[$i]#"$baseDir"%"/"}"对我不起作用。

Here is a simpler version. 这是一个简单的版本。

#!/bin/bash
dir=("/home/user/Documents/" "/home/user/Music/" "/home/user/Videos/" "/home/user/Photos/")

for d in "${dir[@]}"
do
  basename "$d"
done

Please note the argument to basename needs to be quoted, or else directory names with some characters (such as spaces) will cause problems. 请注意,basename的参数需要加引号,否则带有某些字符(例如空格)的目录名称将引起问题。

The inside of the loop could also be replaced by the builtins-based solutions below (faster and without external dependencies) : 循环的内部也可以被下面基于内置的解决方案所取代(更快并且没有外部依赖):

  d="${d%/}"
  echo "${d##*/}"

If you're looking for a one-liner using substitution, this'll work: 如果您正在寻找使用替代品的单线飞机,那么它将起作用:

dir=("/home/user/Documents/" "/home/user/Music/" "/home/user/Videos/" \
"/home/user/Photos/")
baseDir="/home/user/"
dir=("${dir[@]%/}")    ## This line removes trailing forward slashes
printf "%s\n" "${dir[@]#$baseDir}"

You could use basename which returns just the base file name. 您可以使用basename ,它仅返回基本文件名。 In this case, your file is the directory. 在这种情况下,您的文件就是目录。

#!/bin/bash
dir=("/home/user/Documents/" "/home/user/Music/" "/home/user/Videos/" "/home/user/Photos/")

for i in "${!dir[@]}"
do
  echo $( basename ${dir[$i]})
done

As far as I know bash does not handle "double parameter expansion" (I believe zsh does). 据我所知,bash不能处理“双参数扩展”(我相信zsh可以)。 However, you can hack together a solution like this: 但是,您可以一起破解这样的解决方案:

dir=("/home/user/Documents/" "/home/user/Music/" "/home/user/Videos/" "/home/user/Photos/")
trunk=/home/user/

echo $(dir=( "${dir[@]##${trunk}}" ); echo "${dir[@]%/}")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM