我正在尝试编写一个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中做这个?
谢谢你的帮助
可以使用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需要.