string - 在 shell 中进行这种字符串转换的最佳方法是什么?
问题描述
我正在尝试编写一个需要转换以下形式的输入的 shell 脚本:
foo/bar/baz/qux.txt
bar/baz/quz.txt
baz/quz/foo.txt
进入:
baz-qux
quz
foo
即拆分'/',删除前2 段,删除'.txt' 并用剩余的斜杠替换连字符。
使用 tr 进行替换似乎很简单:
paths=$(cat <<- EOF
foo/bar/baz/qux.txt
bar/baz/quz.txt
baz/quz/foo.txt
EOF
)
echo $paths | tr '/' '-' | tr '.txt' ' '
我尝试过各种形式的
cut -d '/' -f x
获得必要的部分,但我来不及。
我是一个红宝石人,很想伸手去拿我的锤子,只用红宝石:
lines.each { |s| s.split('/')[2..-1].join('-').split('.')[0] }
但是为这一操作部署 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
给出:
baz-qux
quz
foo
这些都是bash
shell 内置结构,因此不需要像cut
,sed
或tr
所需的外部进程。
推荐阅读
- python - Altair 折线图中的工具提示
- list - Prolog:比较列表元素和总和
- c++ - C++ 中 fstream 的行为
- github - GitHub 与 IntelliJ(提交)
- grafana - 在 Grafana 中绘制两个 Prometheus 数据源值的总和
- powerbi - 如何使用每天更新的 Excel 创建 Power Bi 报告
- java - Console.getLine 和 Console.getString 不接受所有用户输入 - JAVA
- javascript - 如何使用 Object.defineProperties()?
- javascript - How to skip span element using jQuery next function?
- c++ - 将文件夹复制到构建目录 Visual Studio C++