【问题标题】:How to extract part of a file name with find and awk如何使用 find 和 awk 提取文件名的一部分
【发布时间】:2017-06-30 22:10:21
【问题描述】:

我有这个目录结构

sample1__app
sample2__test

我想提取 sample1sample2 然后做进一步的操作,但我卡在这个

find . -type d -maxdepth 1 -mindepth 1 -exec awk -d'__' '{print $0}' {}  \;

【问题讨论】:

    标签: bash ubuntu awk find


    【解决方案1】:

    您的awk 命令正在尝试打开 文件(在本例中为目录)并处理它们的内容, awk 并不热衷于这样做。

    而且,无论如何,awk 中的 $0整个 输入行 - 我怀疑您想要第一个字段,即 $1

    您真正想要的是处理目录名称本身(而不是其内容),您可以这样做:

    find . -maxdepth 1 -mindepth 1 -type d | awk -F'__' '{ sub ("^./", "", $1); print $1 }'
    

    您只需通过awkfind 的输出通过管道传输,而不是将目录名称作为输入文件提供给它。 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]
    

    【讨论】:

    • 谢谢。是否有可能在结束后我可以使用 -exec 然后使用另一个命令,但我想要几个打开提取的名称,如 -exec mv {}.tar.gz /tmp 等
    • @Mr.Mirror,最好的办法是创建一个 shell 脚本,它接收 "{}" 作为参数,并将其作为 "$1" 执行 - 这样你就可以在脚本而不必与经常引起焦虑的find 语法作斗争:-) 作为一个有用的副作用,这也可以解决答案中购买的换行问题。
    • 实际上我想要快速而肮脏的东西是为了移动。我不会再次使用它,所以正在考虑使用它
    • 我也会在文件名中添加空格到邪恶列表中。
    • 如何在该示例简单 mv {}_tar b/ 之后添加第二个 exec 语句
    猜你喜欢
    • 2019-10-28
    • 1970-01-01
    • 1970-01-01
    • 2014-02-11
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    • 1970-01-01
    • 2012-07-01
    相关资源
    最近更新 更多