【发布时间】:2017-06-30 22:10:21
【问题描述】:
我有这个目录结构
sample1__app
sample2__test
我想提取 sample1 和 sample2 然后做进一步的操作,但我卡在这个
find . -type d -maxdepth 1 -mindepth 1 -exec awk -d'__' '{print $0}' {} \;
【问题讨论】:
我有这个目录结构
sample1__app
sample2__test
我想提取 sample1 和 sample2 然后做进一步的操作,但我卡在这个
find . -type d -maxdepth 1 -mindepth 1 -exec awk -d'__' '{print $0}' {} \;
【问题讨论】:
您的awk 命令正在尝试打开 文件(在本例中为目录)并处理它们的内容, awk 并不热衷于这样做。
而且,无论如何,awk 中的 $0 是 整个 输入行 - 我怀疑您想要第一个字段,即 $1。
您真正想要的是处理目录名称本身(而不是其内容),您可以这样做:
find . -maxdepth 1 -mindepth 1 -type d | awk -F'__' '{ sub ("^./", "", $1); print $1 }'
您只需通过awk 将find 的输出通过管道传输,而不是将目录名称作为输入文件提供给它。 sub 将从输出中去除前导 ./,之后您只需打印出该字段。
顺便说一句,您可能需要注意奇怪的边缘情况,例如带有换行符的目录名称。我已针对您的特定数据定制了这个答案,它应该适用于更简单的边缘情况(例如其中包含空格的文件名),但换行符会导致问题。
我个人的观点是,用换行符、退格符等来构造文件名的人是邪恶的,他们应该得到他们所得到的一切:-)
但是,如果您真的需要处理嵌入的换行符,则可以通过不在find-to-awk 管道中拆分这些文件名来实现。为此,请创建一个使用引号正确处理一个参数的脚本(例如,proc.sh):
#!/usr/bin/env bash
bit="$1" # Get the argument.
bit="${bit#\./}" # Remove ./ at start.
bit="${bit%__*}" # Remove from last __ onward (use %% for first).
echo "[$1] [${bit}]" # Show effect.
然后从 find 本身内部调用它(再次引用以确保参数不被拆分):
find . -maxdepth 1 -mindepth 1 -type d -exec ./proc.sh "{}" ';'
运行带有子目录的目录(XX 是嵌入的换行符):
dodgy__extXXwith-newline/
sample1__app/
sample2__test/
将正确处理它(注意“狡猾”文件的多行 [...],为了便于阅读,输出已稍微重新格式化):
[./sample2__test] [sample2]
[./sample1__app] [sample1]
[./dodgy__ext
with-newline] [dodgy]
【讨论】:
"{}" 作为参数,并将其作为 "$1" 执行 - 这样你就可以在脚本而不必与经常引起焦虑的find 语法作斗争:-) 作为一个有用的副作用,这也可以解决答案中购买的换行问题。