首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ksh参数展开:用-

ksh参数展开:用-
EN

Unix & Linux用户
提问于 2023-05-19 12:16:47
回答 2查看 43关注 0票数 1

说我有这个:

代码语言:javascript
复制
str="@test/string"
echo $str
@test/string
echo ${str#@}
test/string

按预期工作,但是

代码语言:javascript
复制
echo ${str//\//-}
ksh: ${str//\//-}: bad substitution

失败了。(预期@test-string)

替换这样的字符的正确方法是什么?

代码语言:javascript
复制
echo $KSH_VERSION
KSH version @(#)PD KSH v5.2.14 99/07/13.2
EN

回答 2

Unix & Linux用户

发布于 2023-05-19 17:24:10

pdksh shell是OpenBSD上新用户的默认shell,它没有您提到的非标准参数替换。

要用一些新字符串替换某些模式的所有不重叠匹配,可以使用sed

代码语言:javascript
复制
str=$( printf '%s\n' "$str" | sed 's/PATTERN/REPLACEMENT/g' )

请注意,这使用PATTERN作为POSIX基本正则表达式,REPLACEMENT必须转义&\1和其他sed将以特殊方式解释的字符串,并且命令替换从字符串的末尾删除所有尾随的换行符。

示例:

代码语言:javascript
复制
$ str=@title/section1/section2
$ str=$( printf '%s\n' "$str" | sed 's/\//-/g' )
$ printf '%s\n' "$str"
@title-section1-section2

在这种情况下,当只替换单个字符时,可以用sed替换y/\//-/,或者用tr命令tr / -替换整个sed命令。

您还可以选择编写shell循环:

代码语言:javascript
复制
while true; do
    case $str in
        *PATTERN*)
            str=${str%%PATTERN*}REPLACEMENT${str#*PATTERN}
            ;;
        *)
            break
    esac
done

在这段代码中,PATTERN是一个shell模式(“文件名全局模式”)。代码重复使用替换字符串替换字符串中模式的第一个匹配,直到没有更多匹配。由于循环的存在,不能保证以后的迭代不会在先前插入的替换字符串中执行替换。

示例:

代码语言:javascript
复制
$ str=@title/section1/section2
$ while true; do case $str in (*/*) str=${str%%/*}-${str#*/} ;; (*) break; esac; done
$ printf '%s\n' "$str"
@title-section1-section2
票数 1
EN

Unix & Linux用户

发布于 2023-05-19 12:26:32

肯定是一种更好的方法,但是:

代码语言:javascript
复制
$(echo "$str" | tr '/' '-')
票数 -1
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/746349

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档