在shell中进行字符串转换的最佳方法是什么?

1 string bash shell awk sh

我正在尝试编写一个shell脚本,需要转换以下形式的输入:

foo/bar/baz/qux.txt
bar/baz/quz.txt
baz/quz/foo.txt
Run Code Online (Sandbox Code Playgroud)

成:

baz-qux
quz
foo
Run Code Online (Sandbox Code Playgroud)

即分为'/',删除前两个段,删除'.txt'并用剩余的斜杠替换连字符.

使用tr,替换似乎很简单:

paths=$(cat <<- EOF
foo/bar/baz/qux.txt
bar/baz/quz.txt
baz/quz/foo.txt
EOF
)

echo $paths | tr '/' '-' | tr '.txt' ' '
Run Code Online (Sandbox Code Playgroud)

我尝试了各种形式的

cut -d '/' -f x
Run Code Online (Sandbox Code Playgroud)

为了得到必要的细分,但我的时间很短.

我是一个红宝石的家伙,很想找到我的锤子,只是使用红宝石:

lines.each { |s| s.split('/')[2..-1].join('-').split('.')[0] }
Run Code Online (Sandbox Code Playgroud)

但是为这一项操作部署ruby似乎可能有点矫枉过正.而且我想提高我的shell技能,所以想知道是否有更优雅的方式,任何人都会建议在shell中做这个?

谢谢你的帮助

cda*_*rke 6

可以使用bash 参数扩展来完成:

for name in foo/bar/baz/qux.txt bar/baz/quz.txt baz/quz/foo.txt; do
    new=${name#*/}   # drop the shortest prefix match for */, thus everything up to first /
    new=${new#*/}    # repeat, dropping the second segment
    new=${new%.txt}  # drop shortest suffix match for .txt
    new=${new//\//-} # convert any remaining slashes
    echo "$new"
done
Run Code Online (Sandbox Code Playgroud)

得到:

baz-qux
quz
foo
Run Code Online (Sandbox Code Playgroud)

这些都是bashshell内置结构,因此无需外部进程一样cut,sed或tr需要.