AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 706932
Accepted
Olaf
Olaf
Asked: 2022-06-22 00:49:52 +0800 CST2022-06-22 00:49:52 +0800 CST 2022-06-22 00:49:52 +0800 CST

仅递归列出文件的路径

  • 772

为什么

我有两个文件夹应该包含完全相同的文件,但是,当我查看文件数量时,它们是不同的。我想知道一个文件/文件夹中存在哪些文件/文件夹,而不是另一个。我的想法是我将列出所有文件,然后使用 comm 查找两个文件夹之间的差异。

问题

如何以 /path/to/dir 和 /path/to/dir/file 格式递归地列出文件和文件夹?

重要笔记

操作系统:Windows 11,子系统 Ubuntu 20.04.4 LTS

位置文件夹:一个网络驱动器,一个本地驱动器

文件夹大小:每个~2tb

find diff
  • 3 3 个回答
  • 59 Views

3 个回答

  • Voted
  1. Stéphane Chazelas
    2022-06-22T08:26:06+08:002022-06-22T08:26:06+08:00

    请注意, Unix 上的目录只是众多文件类型中的一种。使用find,您可以使用 搜索它们-type d,或使用/zsh glob 中的限定符。其他类型的文件包括常规文件(-type f, .glob 限定符,可能是您所说的file),还有符号链接(-type l/ @)、设备、fifos、套接字......

    要获取目录类型的文件,您可以执行以下操作:

    find dir1/ -type d
    

    对于任何其他类型的文件:

    find dir1/ ! -type d
    

    对于dir2.

    现在有3个主要问题:

    • 打印的路径将以 for 开头,for会使dir1/比较更加困难。dir1dir2/dir2
    • 顺序将是随机的。
    • 文件路径每行写入一个,但换行符与文件路径中的任何字符一样有效,或者换句话说,文件路径可以由多行组成,因此输出不能可靠地进行后处理。

    可以使用 GNUfind并sort使用以下方法解决这些问题:

    find dir1/ -type f -printf '%P\0' | LC_ALL=C sort -z
    

    在哪里:

    • %P打印文件相对于 dir1的路径
    • 我们对列表进行排序(在 C 语言环境中,因为文件路径不必由文本组成)
    • 我们使用 NUL 分隔的记录而不是行,因为 0 是文件路径中唯一不能出现的字节。

    现在,您可以将列表与以下内容进行比较:

    list() {
      find "$@" -printf '%P\0' | LC_ALL=C sort -z
    }
    echo Directory differences:
    comm -z3 <(list dir1/ -type d) <(list dir2/ -type d) | tr '\0' '\n'
    echo Non-directory differences:
    comm -z3 <(list dir1/ ! -type d) <(list dir2/ ! -type d) | tr '\0' '\n'
    

    该输出不能可靠地进行后处理,因为我们将 NUL 转换回换行符以显示并comm使用 TAB 来分隔在文件路径中再次有效的列。

    或者,您可以获取 zsh 数组中的列表并使用其数组比较运算符:

    dirs_in_dir1=( dir1/**/*(ND/:s:dir1/::) )
    dirs_in_dir2=( dir2/**/*(ND/:s:dir2/::) )
    nondirs_in_dir1=( dir1/**/*(ND^/:s:dir1/::) )
    nondirs_in_dir2=( dir2/**/*(ND^/:s:dir2/::) )
    

    然后:

    dirs_only_in_dir1=( ${dirs_in_dir1:|dirs_in_dir2} )
    dirs_only_in_dir2=( ${dirs_in_dir2:|dirs_in_dir1} )
    nondirs_only_in_dir1=( ${nondirs_in_dir1:|nondirs_in_dir2} )
    nondirs_only_in_dir2=( ${nondirs_in_dir2:|nondirs_in_dir1} )
    

    并对这些数组做你必须做的事情,就像print他们r在 olumn 上的 aw一样1 C:

    print -rC1 -- $array
    

    (或NUL 分隔,因此可以通过添加-N选项对其进行后处理)。

    • 1
  2. Best Answer
    terdon
    2022-06-22T00:58:00+08:002022-06-22T00:58:00+08:00

    您不需要任何这些,只需使用diff -qr dir1 dir2. 例如:

    $ tree
    .
    ├── dir1
    │   ├── file1
    │   ├── file3
    │   ├── file4
    │   ├── file6
    │   ├── file7
    │   ├── file8
    │   └── subdir1
    │       ├── dsaf
    │       ├── sufile1
    │       └── sufile3
    └── dir2
        ├── file1
        ├── file2
        ├── file3
        ├── file4
        ├── file9
        └── subdir1
            ├── sufile1
            └── sufile3
    
    4 directories, 16 files
    

    如果我现在在两个目录上运行diff -qr(-r对于“递归”并且-q仅在文件不同时报告,而不显示实际差异),我得到:

    $ diff -qr dir1/ dir2/
    Only in dir2/: file2
    Only in dir1/: file6
    Only in dir1/: file7
    Only in dir1/: file8
    Only in dir2/: file9
    Only in dir1/subdir1: dsaf
    

    也就是说,获取文件列表的方法是find:

    $ find dir1 -type f
    dir1/subdir1/dsaf
    dir1/subdir1/sufile1
    dir1/subdir1/sufile3
    dir1/file6
    dir1/file1
    dir1/file8
    dir1/file4
    dir1/file7
    dir1/file3
    

    然后,您可以删除dir1/和dir2/using ,并在支持它的 shell 中使用进程替换sed来比较两个目录的输出:

    $ comm -3 <(find dir1 -type f | sed 's|dir1/||' | sort) <(find dir2 -type f | sed 's|dir2/||' | sort)
        file2
    file6
    file7
    file8
        file9
    subdir1/dsaf
    

    请注意,这假定文件名没有换行符。如果您需要处理这些,只需使用上述diff -r方法。

    • 0
  3. Archemar
    2022-06-22T00:59:23+08:002022-06-22T00:59:23+08:00

    尝试

     cd /path/1
     find . -type d -print | sort > list1.dir
     find . -type f -print | sort > list1.file
     cd /path/2
     find . -type d -print | sort > list2.dir
     find . -type f -print | sort > list2.file
    
    • sort用于确保相同的顺序,以及较小的结果difforcomm
    • 您可以使用绝对目标文件名,这样list1.file就list2.file不会“污染”结果。
    • 0

相关问题

  • 将变量从子shell打印到父shell [重复]

  • 检查某个文件夹是否存在于某个目录中

  • 从命令行查找和替换 CSS 文件中的颜色

  • git:仅在 GUI 中使用视觉差异(融合)

  • GNU find:在-exec中获取绝对和相对路径

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve