【问题标题】:Find files and print only their parent directories查找文件并仅打印其父目录
【发布时间】:2012-03-24 17:48:36
【问题描述】:

我有以下命令。无论.user.log 文件在哪里,我们都需要打印父目录(即hhtwee1。)如何做到这一点?

$ cd /nfs//office/ && find . -name '.user.log'
./hht/info/.user.log
./wee1/info/.user.log

【问题讨论】:

    标签: linux shell command


    【解决方案1】:
    for file in $(find /nfs/office -name .user.log -print)
    do
        parent=$(dirname $(dirname $file))
        echo $parent
    done
    

    编辑:抱歉错过了您想要祖父母目录。

    【讨论】:

      【解决方案2】:
      find /nfs/office -name '.user.log' | while read line
      do
          echo $line | awk -F/ '{print $(NF-1),$NF}'
      done
      

      【讨论】:

        【解决方案3】:

        你可以这样做:

        cd /nfs/office/ && find . -name '.user.log' | xargs -n1 -I{} expr match {} '\(\.\(\/[^/]*\/\)\?\)'
        

        xargs 使用expr match 提取以. 开头的部分,直到斜线字符之间的第一个目录匹配 (/dir/)。

        使用sed 的替代版本如下:

        cd /nfs/office/ &&  find . -name 'file.txt' | sed -r 's|(\./([^/]*/)?).*|\1|'
        

        【讨论】:

          【解决方案4】:

          @trojanfoe 有正确的想法; this 只是让它与 any 文件名以及循环中的几乎所有命令一起安全工作的一种方法:

          while IFS= read -r -d '' -u 9
          do
              echo "$(dirname -- "$(dirname -- "$REPLY")")"
          done 9< <( find "/nfs/office/" -name '.user.log' -print0 )
          

          如果您希望它只回显唯一名称:

          while IFS= read -r -d '' -u 9
          do
              echo "$(dirname -- "$(dirname -- "$REPLY")")"
          done 9< <( find "/nfs/office/" -name '.user.log' -print0 ) | sort -u
          

          【讨论】:

          • 您使用不同的文件描述符有什么特别的原因吗?
          • 如果你想在循环中使用标准输入。上面的链接中对此进行了解释。
          【解决方案5】:

          我在这里错过了什么吗?当然,所有这些正则表达式和/或循环都不是必需的,单行就可以完成这项工作。当路径名中有空格时,“for foo in $()”解决方案也会失败。

          只需将 dirname 与 xargs 一起使用两次,即可获取父级的父级...

          # make test case
          mkdir -p /nfs/office/hht/info
          mkdir -p /nfs/office/wee1/info
          touch /nfs/office/hht/info/.user.log
          touch /nfs/office/wee1/info/.user.log
          
          # parent's parent approach
          cd /nfs//office/ && find . -name '.user.log' | xargs -I{} dirname {} | xargs -I{} dirname {}
          
          # alternative, have find print parent directory, so dirname only needed once...
          cd /nfs//office/ && find . -name ".user.log" -printf "%h\n"  | xargs -I{} dirname {}
          

          生产

          ./hht
          ./wee1
          

          【讨论】:

          • 我能不能找到结果目录的权限? -name '.user_repo.log' | xargs -i{} 目录名 {} | xargs -i{} 目录名 {} |xargs ll
          • 假设你指的ll是“ls -lA”的常用别名,那么不是。 xargs 只会运行命令,而不是别名。但是,您可以改用“xargs ls -lA”...
          • 请注意,xargs-i 标志已被弃用,最好使用 -I 标志。
          【解决方案6】:

          您可以使用find-printf 操作的格式选项轻松完成此操作(请参阅man find)。

          cd /nfs//office/ && find . -name '.user.log' -printf "%h\n"
          ./hht/info
          ./wee1/info
          

          来自man page

          %h\n 将在新行上打印每个文件的路径。

          请注意-printf 仅适用于 GNU。它不适用于 macOS(BSD 系统)。

          【讨论】:

            【解决方案7】:
            find -type f -exec bash -c 'echo "${1%/*}"' bash {} \;
            

            【讨论】:

            【解决方案8】:
            for i in $(find . -name ".user.log" -exec readlink -f {} \;)
            do 
                 parent=$(dirname $i)
                 echo $parent
            done
            

            这可能会起作用并产生类似的输出

            /nfs/office/hht/info

            /nfs/office/wee1/info

            【讨论】:

              猜你喜欢
              • 2018-05-13
              • 1970-01-01
              • 1970-01-01
              • 2023-03-15
              • 1970-01-01
              • 1970-01-01
              • 2014-04-26
              • 1970-01-01
              • 2019-09-03
              相关资源
              最近更新 更多