# e0201-find-xargs **Repository Path**: lxm10034/e0201-find-xargs ## Basic Information - **Project Name**: e0201-find-xargs - **Description**: 供学生练习 find 命令和 xargs 命令所使用的仓库。 - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 214 - **Created**: 2022-03-12 - **Last Updated**: 2022-03-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 练习0201: 选择性地批量复制文件 这是一道供同学们熟悉 Shell 命令行操作的高阶练习题。 题目的要求是构造一个命令行, 将指定目录下符合要求的那一部分文件, 复制到另一个指定的目录下, 同时还要保持文件所处的相对目录结构。 掌握这道题所涉及的命令行知识并加以灵活运用, 将能够轻松解决许多常见的文件搜索和批量文件处理问题, 例如批量重命名、批量删除、批量设置权限, 等等, 而且, 批量操作都可以是有选择性的。 在图形界面下需要用鼠标一遍一遍点击才能完成的笨拙操作, 在命令行下可以轻松解决。 希望同学们由此体会命令行的益处, 体会如何才是像专家那样操作计算机。 ### 解题说明 ```plain 阿里云盘: https://www.aliyundrive.com/s/kjwmVdD6xZE 百度网盘: https://pan.baidu.com/s/1Kpmm1QaRfouqIfPqDhOLOQ 提取码: uih9 ``` 首先, 同学们要从上面的地址下载视频讲解然后认真观看, 着重理解以下的 Shell 基本概念: 1. `pwd` 当前工作目录; `cd` 切换当前工作目录; `ls` 显示目录内容 1. `/` 根目录; `~` 用户主目录; `.` 当前目录; `..` 上一级目录; 相对路径; 绝对路径 1. `man` 查看手册; `less` (或者 `more`) 浏览文本及其操作键 1. 命令 (command); 子命令; 短选项 (option); 长选项; 选项参数; 命令参数 (argument) 1. `*`, `?` 等 wildcards (globs) 通配符 1. `STDIN` 标准输入; `STDOUT` 标准输出; `STDERR` 标准错误输出 1. `>`, `>>`, `2>`, `<` 等输入输出重定向 1. `|` 命令管道 1. `\` Escape 转义字符 这些概念都是成功解题并触类旁通所必须的。 然后, 同学们要使用 `man` 命令来学习 `find` 和 `xargs` 命令的使用手册, 自己寻找解题的思路和办法。 如果因为初学, 觉得使用手册实在晦涩难懂, 可以先根据自己的喜好阅读以下推荐的英文教程: 1. [find - Community Help Wiki - Official Ubuntu Documentation](https://help.ubuntu.com/community/find) 1. [Linux Find Command Tutorial - linuxhint.com](https://linuxhint.com/linux-find-command-tutorial/) 1. [Linux xargs Command - linuxhint.com](https://linuxhint.com/linux-xargs-command/) 1. [How to Use xargs on Linux - linuxhint.com](https://linuxhint.com/xargs_linux/) 但仅仅阅读以上教程对于解决本题还是不够的。最终解题还是要靠手册。 阅读英文对于编程非常重要, 因为计算机技术日新月异, 绝大多数文档只有英文, 根本来不及翻译成其他语言。就算有人翻译了, 品质也没有保障, 术语也难以统一。其实, 无论是英文的教程 (tutorial)、指南 (guide), ——这些都比较平易近人, 还是英文的文档 (documentation)、手册 (manual), ——这些都相对地比较 technical, 只要坚持经常阅读, 很快就能适应, 因为涉及的单词并不多, 比文学作品易读得多。 最后, 需要强调: 答案只是一行命令 (可能需要一些简单的命令作准备, 但最关键的只有一行), 但同学们务必不要相互打听答案。 就算有同学向你求助, 也请尽量不要直接告诉别人答案, 给自己和别人都留下独立成长的机会。如果实在不会, 建议反复观看几遍视频讲解, 反复翻看几遍手册, 多多操作, 检验自己的理解。如果确实需要帮助, 可以问老师, 老师会把握好提示的尺度。 老师能讲的其实非常有限。学会自学, 对接下来的课程学习至关重要。 ### 具体要求 克隆代码仓库至本地后, 运行以下命令 ``` $ python script/make_files1.py ``` 将生成 `files1` 文件夹。`files1` 文件夹内将有 4 个子文件夹, 每个子文件夹内都有 50 个文件。 这 50 个文件, 随机地, 约有 20% 的文件内容是 `ok` (2 字节), 其余约 80% 的文件内容是 `important` (9 字节)。 你的任务是, 将 9 字节大小的那些文件复制到 `files1-selected` 文件夹下, 而且要保留这些文件原本的相对目录结构。例如, `files1` 目录的内容如果是 ``` $ tree files1 files1 ├── aaaa │   ├── 0000.txt │   ├── 0101.txt ... │   ├── 4848.txt │   └── 4949.txt ├── bbbb │   ├── 0000.txt │   ├── 0101.txt ... │   ├── 4848.txt │   └── 4949.txt ├── cccc │   ├── 0000.txt │   ├── 0101.txt ... │   ├── 4848.txt │   └── 4949.txt └── dddd ├── 0000.txt ├── 0101.txt ... ├── 4848.txt └── 4949.txt ``` 那么解题完成后, `files1-selected` 目录的内容应该是 ``` $ tree files1-selected files1-selected ├── aaaa │   ├── 0000.txt │   ├── 0202.txt ... │   ├── 4747.txt │   └── 4949.txt ├── bbbb │   ├── 0000.txt │   ├── 0101.txt ... │   ├── 4747.txt │   ├── 4848.txt ├── cccc │   ├── 0303.txt │   ├── 0505.txt ... │   ├── 4747.txt │   └── 4949.txt └── dddd ├── 0101.txt ├── 0202.txt ... ├── 4747.txt └── 4848.txt ``` 其中的 `.txt` 文件都是大小为 9 字节的。 以上只是第一小题, 还有更进一步的扩展。运行以下命令 ``` $ python script/make_files2.py ``` 将生成 `files2` 文件夹。其内容与 `files1` 类似, 所不同的是, `.txt` 的文件名将包含有单引号 `'`、双引号 `"`、空格 ` ` 等 “不良” 字符。例如, `files2` 目录的内容会是 ``` files2 ├── eeee │   ├── '00' "00".txt │   ├── '01' "01".txt ... │   ├── '48' "48".txt │   └── '49' "49".txt ├── ffff │   ├── '00' "00".txt │   ├── '01' "01".txt ... │   ├── '48' "48".txt │   └── '49' "49".txt └── gggg ├── '00' "00".txt ├── '01' "01".txt ... ├── '48' "48".txt └── '49' "49".txt ``` 你的第二个任务与第一个任务类似, 同样是要将 `files2` 下 9 字节大小的那些文件复制到 `files2-selected` 文件夹下, 而且要保留这些文件原本的相对目录结构。然而, 文件名里含有这些 “不良” 字符, 会给 `find`、`xargs` 命令造成一些麻烦。但通过查阅 `man` 手册, 我希望你能够找到解决这一问题的相应选项。 另外, 解决本题可能还需要看一看 `cp` 命令的手册。而在 macOS 操作系统上, 由于其内置的 BSD 命令工具集与 Ubuntu 内置的 GNU 命令工具集存在一点点差异, 其 `cp` 命令恐怕还不足以解决本题。在 macOS 操作系统上可以考虑用 `rsync` 命令代替 `cp` (没有的话可以用 `brew install rsync` 命令来安装), 如何使用 `rsync` 还是要看手册。 最后需要说明的是, 本题确实存在相当的难度, 同学们如果做不出来, 其实是正常的, 不必背负太大的心理压力, 也不影响成绩 (但不做或者不学, 肯定会影响成绩哦)。这只是一个练习, 练习未必一定要成功。经过练习和思考, 同学们能够理解 Shell 的基本概念, 能够开始阅读英文文档, 就已经达到教学目的了。修行在个人, just have fun! 本题目因此将不公布答案。如果你成功通过了 `pytest`, 像 [练习 0101](https://gitee.com/cueb-fintech/e0101-terminal) 那样提交 PR 即可, 但答案请替我保密哦 ;)