Home | 简体中文 | 繁体中文 | 杂文 | Github | 知乎专栏 | Facebook | Linkedin | Youtube | 打赏(Donations) | About
知乎专栏

第 2 章 目录和文件

目录

2.1. dirname - 提取目录部分
2.2. basename - 提取文件名部分
2.2.1. 排除扩展名
2.2.2. 取扩展名
2.3. file — determine file type
2.4. stat
2.5. file – determine file type
2.6. mkdir - make directories
2.7. rename
2.8. touch
2.9. truncate
2.10. ls - list directory contents
2.10.1. full-time / time-style 定义日期时间格式
2.11. cp - copy files and directories
2.11.1. copy directories recursively
2.11.2. 覆盖已存在的文件
2.11.3. -a, --archive same as -dR --preserve=all
2.12. rm - remove files or directories
2.12.1. -bash: /bin/rm: Argument list too long
2.12.2. zsh: sure you want to delete all the files in /tmp [yn]?
2.13. df - report file system disk space usage
2.14. du - estimate file space usage
2.15. tac - concatenate and print files in reverse
2.16. split - split a file into pieces
2.16.1. 按行分割文件
2.16.2. 按尺寸分割文件
2.17. find - search for files in a directory hierarchy
2.17.1. 多目录匹配
2.17.2. name
2.17.3. regex
2.17.4. user
2.17.5. perm
2.17.6. type
2.17.7. -delete
2.17.8. exec
2.17.9. 排除目录
2.17.10. -ctime / -cmin - 按状态改变时间查找
2.17.11. -mtime / -mmin - 按修改时间查找
2.17.12. --newer
2.17.13. -print / -printf
2.17.14. -size
2.17.15. -path
2.17.16. 目录深度控制
2.17.17. xargs
2.17.18. 查看空文件

2.1. dirname - 提取目录部分

dirname 命令用于提取文件路径中的目录部分,即去掉最后一个斜杠及其后面的内容。

基本语法

dirname [选项] 名称...
dirname [选项]
			

常用选项:

  • -z, --zero - 输出以 NUL 结尾而非换行符

  • --help - 显示帮助信息

  • --version - 显示版本信息

基本用法示例

提取文件路径的目录部分:

$ dirname /usr/bin/find
/usr/bin

$ dirname /etc/nginx/nginx.conf
/etc/nginx

$ dirname /var/log/
/var

$ dirname /usr/local/bin/
/usr/local
			

处理多个路径参数:

$ dirname /usr/bin/find /etc/nginx/nginx.conf /var/log/syslog
/usr/bin
/etc/nginx
/var/log
			

相对路径处理:

$ dirname ./bin/script.sh
./bin

$ dirname ../data/file.txt
..

$ dirname script.sh
.
			

特殊路径处理:

$ dirname /
/

$ dirname file
.

$ dirname ""
.

$ dirname //usr//bin//find
//usr//bin
			

实际应用

在脚本中获取脚本所在目录:

#!/bin/bash
# 获取脚本所在目录的绝对路径
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
echo "脚本目录: $SCRIPT_DIR"
			

批量移动文件到上级目录:

for file in /tmp/logs/*.log; do
    dir=$(dirname "$file")
    mv "$file" "$dir/../"
done
			

创建目录结构:

file="/var/www/html/index.html"
mkdir -p "$(dirname "$file")"
touch "$file"
			

备份文件时保留目录结构:

src="/etc/nginx/nginx.conf"
backup_dir="/backup/$(dirname "$src")"
mkdir -p "$backup_dir"
cp "$src" "$backup_dir/"
			

与 basename 对比

dirname 提取目录部分,basename 提取文件名部分,两者互补:

$ path="/usr/bin/find"
$ dirname "$path"
/usr/bin
$ basename "$path"
find

# 组合使用
$ echo "目录: $(dirname "$path"), 文件: $(basename "$path")"
目录: /usr/bin, 文件: find
			

Shell 参数展开替代

在 Bash 中可以使用参数展开实现 dirname 的功能:

path="/usr/bin/find"

# dirname 等价于
echo "${path%/*}"    # 输出: /usr/bin

# basename 等价于
echo "${path##*/}"   # 输出: find

# 特殊情况处理
path="file.txt"
echo "${path%/*}"    # 输出: file.txt (不是 ".")
dirname "$path"      # 输出: .
			

注意:参数展开在处理不含斜杠的路径时行为与 dirname 不同,dirname 会返回 "."。

常见陷阱

处理包含空格的路径时必须加引号:

# 错误 - 空格会导致参数分割
dirname /path/with spaces/file.txt
# 输出: /path/with

# 正确 - 使用引号
dirname "/path/with spaces/file.txt"
# 输出: /path/with spaces
			

尾随斜杠的处理:

$ dirname /usr/bin/
/usr
$ dirname /usr/bin
/usr

# 如果需要保留尾随斜杠,先去除再处理
path="/usr/bin/"
dirname "${path%/}"  # 输出: /usr