如何从 Bash 中的字符串中去除或替换模式的所有匹配项?
How to strip or replace all matches of a pattern from a string in Bash?
我正在尝试在 Bash 中编写 dirname 函数,这样它就不会使用任何外部命令。
function dirname() {
local path=
[[ $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}
语法进行全局替换。
模式是 \/+(\/)
(带有转义斜杠,因为 /
是定界符),实际上是 /+(/)
(其中 +(/)
表示 "one or more slashes") .
我正在尝试在 Bash 中编写 dirname 函数,这样它就不会使用任何外部命令。
function dirname() {
local path=
[[ $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}
语法进行全局替换。
模式是 \/+(\/)
(带有转义斜杠,因为 /
是定界符),实际上是 /+(/)
(其中 +(/)
表示 "one or more slashes") .