Skip to content

Unix / Linux - 文件管理

在类 Unix 环境中高效工作,有效的文件管理至关重要。本章涵盖了创建、查看、修改、组织和删除文件的基本命令。

在 Unix 中,几乎所有东西都被视为文件。你将会遇到的主要类型有:

  • 普通文件(Ordinary Files):包含数据,如文本、图像或程序代码/可执行文件。
  • 目录(Directories):是一种特殊文件,用于存放其他文件和目录。
  • 特殊文件(Special Files):表示设备(如硬盘 /dev/sda、终端 /dev/tty)或通信通道(sockets、pipes)。
  • 软链接(Symbolic Links):指向其他文件或目录的指针。

ls 命令用于列出目录内容。有关其选项(如 -l、-a、-h 等)的更多详细信息,请参见 ‘目录管理’ 章节。

$ ls
file1.txt notes.md project_dir
$ ls -lh project_dir
total 4.0K
-rw-r--r-- 1 user group 1.2K Jul 25 15:00 main.c

file 命令检查文件内容并尝试确定其类型。

$ file file1.txt
file1.txt: ASCII text
$ file /bin/bash
/bin/bash: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=..., stripped
$ file project_dir
project_dir: directory
$ file image.jpg
image.jpg: JPEG image data, JFIF standard 1.01, resolution (DPI), density 72x72, segment length 16, baseline, precision 8, 1920x1080, frames 3

Shell 会解释特殊字符(元字符或通配符)来匹配多个文件名。这称为 Globbing。

  • *: 匹配零个或多个字符。*.txt 匹配 file1.txt、report.txt、.txt。
  • ?: 精确匹配一个字符。file?.txt 匹配 file1.txt、fileA.txt,但不匹配 file10.txt。
  • [...]: 匹配括号内的任意一个字符。[abc]*.log 匹配以 a、b 或 c 开头且以 .log 结尾的文件。可以使用范围:[a-z]*.dat 匹配以任意小写字母开头的文件。

使用 ls 命令的示例:

# 列出所有以 .log 结尾的文件
$ ls *.log
app.log kernel.log sys.log
# 列出以 'data' 开头后跟单个数字的文件
$ ls data?.csv
data1.csv data3.csv
# 列出以 'img' 开头后跟 '[abc]' 的文件
$ ls img[abc].jpg
imga.jpg imgc.jpg

文件名以点号 (.) 开头的文件被视为隐藏文件。ls 默认不显示它们;使用 ls -a 或 ls -A(-A 会忽略 . 和 ..)。

隐藏文件常用于配置文件(例如 ~/.bashrc、~/.vimrc、~/.ssh/config)或目录(~/.config、~/.local)。

$ ls -a ~
. .. .bash_history .bashrc .profile .ssh .vimrc Documents Downloads Music

touch 命令是创建空文件或更新现有文件修改时间戳的标准方法。

# 创建一个名为 new_file.txt 的空文件
$ touch new_file.txt
# 创建多个空文件
$ touch data.log config.yml
# 更新 existing_file.md 的时间戳
$ touch existing_file.md

要创建带有内容的文件,需要使用文本编辑器。常见的命令行编辑器包括:

  • nano: 一个简单、对初学者友好的编辑器。常推荐给新用户。
  • vim (or vi): 一个功能强大、无处不在的模式化编辑器,学习曲线较陡峭。将在专门的章节详细介绍。
  • emacs: 另一个功能强大、可扩展的编辑器。
# 使用 nano 创建或编辑文件
$ nano my_notes.txt
# 使用 vim 创建或编辑文件
$ vim my_script.py

有几个命令可以显示文件内容:

  • cat (concatenate): 将整个文件内容输出到标准输出。适用于短文件。
  • less: 一个分页器,逐屏显示内容。允许向前/向后滚动(使用箭头键、PageUp/Down)和搜索 (/)。按 q 退出。这是查看大文件时推荐的工具。
  • more: 一个较旧的分页器,与 less 类似但功能较少(例如,向后滚动有限)。通常更推荐使用 less。
  • head: 显示文件的前几行(默认为 10 行)。使用 -n count 指定行数。
  • tail: 显示文件的后几行(默认为 10 行)。使用 -n count。-f 选项(‘follow’)对于监视日志文件非常有用。
# 显示整个短文件
$ cat config.yml
# 交互式查看长文件
$ less /var/log/syslog
# 显示前 5 行
$ head -n 5 data.csv
# 显示后 20 行
$ tail -n 20 results.log
# 实时监控日志文件的新增内容
$ tail -f application.log

wc (word count) 命令统计文件的行数、词数和字节数/字符数。

$ wc report.txt
42 210 1536 report.txt

输出显示:行数 (42),词数 (210),字节数 (1536),文件名。

常用选项:

  • -l: 仅统计行数。
  • -w: 仅统计词数。
  • -c: 仅统计字节数。
  • -m: 统计字符数(对于多字节编码可能与字节数不同)。
$ wc -l *.py
150 script1.py
75 script2.py
225 total

cp (copy) 命令用于复制文件或目录。

语法:cp [options] source destination

# 将 file.txt 复制到同一目录下的 file.bak
$ cp file.txt file.bak
# 将 file.txt 复制到 backup/ 目录(保留原文件名)
$ cp file.txt backup/
# 将 file.txt 复制到 backup/ 目录并重命名为 report_final.txt
$ cp file.txt backup/report_final.txt
# 将多个文件复制到 documents/ 目录
$ cp notes.md report.pdf documents/
# 递归复制目录(必须使用 -r 或 -R)
$ cp -r project/ project_backup/

常用选项:

  • -r 或 -R: 递归复制(用于目录)。
  • -i: 交互式(覆盖前提示)。
  • -v: 详细模式(显示正在复制的文件)。
  • -p: 保留属性,如修改时间和权限。

mv (move) 命令用于重命名文件或将其移动到不同目录。

语法:mv [options] source destination

# 将 oldname.txt 重命名为 newname.txt
$ mv oldname.txt newname.txt
# 将 file.log 移动到 logs/ 目录
$ mv file.log logs/
# 将多个文件移动到 archive/ 目录
$ mv data*.csv results.dat archive/
# 将 file.tmp 移动到 processed/ 目录并重命名为 final.dat
$ mv file.tmp processed/final.dat

常用选项:

  • -i: 交互式(覆盖前提示)。
  • -v: 详细模式(显示操作)。

rm (remove) 命令用于删除文件。请务必谨慎使用,因为从命令行删除的文件通常无法恢复!

语法:rm [options] filename(s)

# 删除 temp_file.txt
$ rm temp_file.txt
# 删除多个文件
$ rm *.tmp data.old
# 递归删除(目录及其内容)- 非常危险!
$ rm -r old_project/
# 交互式删除(每个文件都提示)
$ rm -i *.log

关键选项:

  • -r 或 -R: 递归删除(用于目录)。删除非空目录时需要此选项。
  • -i: 交互式(删除前提示)。建议为了安全使用此选项。
  • -f: 强制删除(抑制提示,如果可能则忽略权限)。请务必极其谨慎使用!

在使用包含通配符 (*) 的 rm 命令执行前,请仔细检查。先运行 ls *.tmp 查看哪些文件将被删除是一个好习惯。

Unix 程序通常通过三个标准数据流进行交互:

  • 标准输入 (stdin, file descriptor 0):默认输入数据源,通常是键盘。
  • 标准输出 (stdout, file descriptor 1):正常程序输出的默认目的地,通常是终端屏幕。
  • 标准错误 (stderr, file descriptor 2):错误消息的默认目的地,通常是终端屏幕。

这些流可以被重定向。例如,> 将标准输出重定向到文件,< 将文件重定向作为标准输入,而 |(管道)则将一个命令的标准输出重定向到另一个命令的标准输入。重定向和管道是强大的概念,将在其他地方更详细地介绍。