如何从Bash中的字符串中删除或替换所有模式的匹配项?
问题描述:
我想在Bash中编写dirname函数,以便它不使用任何外部命令。如何从Bash中的字符串中删除或替换所有模式的匹配项?
function dirname() {
local path=$1
[[ $path =~ ^[^/]+$ ]] && dir=. || { # if path has no slashes, set dir to .
[[ $path =~ ^/+$ ]] && dir=/ || { # if path has only slashes, set dir to/
local IFS=/ dir_a i
read -ra dir_a <<< "$path" # read the components of path into an array
dir="${dir_a[0]}"
for ((i=1; i < ${#dir_a[@]}; i++)); do # strip out any repeating slashes
[[ ${dir_a[i]} ]] && dir="$dir/${dir_a[i]}" # append unless it is an empty element
done
}
}
[[ $dir ]] && printf '%s\n' "$dir" # print only if not empty
}
为了从路径去除任何重复/
,我不得不使用阵列逻辑。有没有更简单的方法来做到这一点Bash Parameter Expansion?我试过了,但我似乎没有把握好。
基本上,我想用单斜杠替换所有出现的多个连续的斜杠。
答
如果extglob
是:
shopt -s extglob
,你可以这样做:
printf '%s\n' "${path//\/+(\/)/\/}"
它使用${var//pattern/replacement}
语法做全局替换。
的图案是\/+(\/)
(带斜线转义因为/
是分隔符),这是真的/+(/)
(其中+(/)
装置“的一个或多个斜线”)。
'echo“$ {path%\/*}”'? – Cyrus
这将只删除最后一个'/'向前。例如:如果path是'a // b // c /// d',它会给我们'a // b // c //'。 – codeforester
只是出于好奇,你在哪里找到像'a // b // c /// d'这样的路径?我唯一遇到的问题是用'drive:\\ a \\ b \\ c \\ file.ext'将其转换为POSIX驱动器:/a/b/c/file.ext '。你在哪里可以创建一个像“a // b // c /// d'这样的路径? windoze?或者,这只是一个通用的*多个''//'' *练习? –