【问题标题】:BASH - find specific folder with find and filter with regexBASH - 使用查找查找特定文件夹并使用正则表达式过滤
【发布时间】:2012-08-17 22:44:30
【问题描述】:

我有一个文件夹,其中包含许多带有子文件夹 (/...) 的文件夹,其结构如下:

_30_photos/combined
_30_photos/singles
_47_foo.bar
_47_foo.bar/combined
_47_foo.bar/singles
_50_foobar

使用命令find . -type d -print | grep '_[0-9]*_' 将显示结构为 ** 的所有文件夹。但是我生成了一个仅捕获 */combined 文件夹的正则表达式: _[0-9]*_[a-z.]+/combined 但是当我将它插入到 find 命令中时,不会打印任何内容。

下一步是为每个组合文件夹(在我的硬盘上的某处)创建一个文件夹,并将组合文件夹的内容复制到新文件夹。新文件夹名称应与子文件夹的父名称相同,例如_47_foo.bar。搜索后可以通过 xargs 命令实现吗?

【问题讨论】:

  • 如果您使用 find 将正则表达式插入 -regex 选项,请注意 find 匹配完整路径 -> 如果您从 .那么正则表达式必须匹配 ./whatever/come.here
  • 这听起来有点像XY Problem。 mybecks,你真正想要达到什么目的?
  • 是否可以告诉 find 它应该只在这个(或预定义的)目录中搜索,当然在所有子目录中
  • @mybecks ...但你所说的不是第一个参数找到的
  • 我曾想过,但意识到所有具有该命名的文件夹都已找到(并已删除,我也使用该 find 命令进行删除)

标签: regex bash


【解决方案1】:

你可以使用这个命令:

find . -type d | grep -P "_[0-9]*_[a-z.]+/combined"

【讨论】:

    【解决方案2】:

    使用基本的grep,您需要转义+

    ... | grep '_[0-9]*_[a-z.]\+/combined'
    

    或者您可以使用“扩展正则表达式”版本(egrepgrep -E [thanks chepner]),其中 + 不必转义。

    xargs 可能不是进行上述复制的最灵活方式,因为与multiple commands 一起使用很棘手。您可能会发现使用 while 循环更灵活:

    ... | grep '_[0-9]*_[a-z.]\+/combined' | while read combined_dir; do 
        mkdir some_new_dir
        cp -r ${combined_dir} some_new_dir/
    done
    

    如果您想要一种自动命名 some_new_dir 的方法,请查看 bash string manipulation

    【讨论】:

    • 如果我这样做 echo $combined_dir 它会打印出整个路径 ./_00_foo.bar/combined。这没关系。但是现在我想将 /combined 的内容复制到主目录(_00_foo.bar)。因此我在循环中使用了以下语法:CURRENT_DIR=$(echo $combined_dir | grep "_[0-9]*_[a-z.]\+") 但我不工作:(
    【解决方案3】:
    target_dir="your target dir"
    
    find . -type d -regex ".*_[0-9]+_.*/combined" | \
      (while read s; do
         n=$(dirname "$s")
         cp -pr "$s" "$target_dir/${n#./}"
       done
      )
    

    注意:

    • 如果目录名称中有换行符“\n”,则会失败
    • 这使用了一个 subshel​​l 来避免你的环境混乱 - 在你不需要的脚本中
    • 稍微改变了正则表达式:[0-9]*[0-9]+

    【讨论】:

      【解决方案4】:

      你不需要grep:

      find . -type d -regex ".*_[0-9]*_.*/combined"
      

      剩下的:

      find . -type d -regex "^\./.*_[0-9]*_.*/combined" | \
         sed 's!\./\(.*\)/combined$!& /somewhere/\1!'   | \
         xargs -n2 cp -r
      

      【讨论】:

        猜你喜欢
        • 2012-11-30
        • 1970-01-01
        • 2022-11-02
        • 2021-05-09
        • 2019-08-19
        • 1970-01-01
        • 2019-04-28
        • 2014-04-16
        • 2013-07-07
        相关资源
        最近更新 更多