linux split命令

命令简介

split 命令用于将一个大文件分割成多个较小的文件。它支持按行数、字节数、文件大小等多种方式进行分割,是处理大文件、日志文件分割、数据分片等场景的实用工具。

特点: split 命令可以高效地处理大型文件,支持多种分割标准,生成的文件可以方便地重新合并。

语法

split [选项] [输入文件 [前缀]]

常用形式:

# 按行数分割
split -l 行数 输入文件 [前缀]

# 按字节数分割
split -b 字节数 输入文件 [前缀]

# 按文件大小分割
split -b 大小 输入文件 [前缀]

常用选项

选项 说明
-l 行数 按行数分割,每个文件包含指定行数
-b 大小 按字节数分割,指定每个文件的大小
-C 大小 按字节数分割,但尽量保持行完整
-d 使用数字后缀而不是字母
-a 长度 指定后缀长度(默认2个字符)
--verbose 显示详细的分割过程
--additional-suffix=后缀 为输出文件添加额外后缀
-n 数量 分割成指定数量的文件
--numeric-suffixes=起始值 使用数字后缀,从指定值开始
--filter=命令 将每个分片写入命令的标准输入

大小格式说明

单位 说明 示例
b 字节(512字节块) 512b = 256KB
k 千字节(1024字节) 1k = 1024字节
M 兆字节(1024KB) 1M = 1048576字节
G 吉字节(1024MB) 1G = 1073741824字节
T 太字节(1024GB) 1T = 1099511627776字节
KB 千字节(1000字节) 1KB = 1000字节
MB 兆字节(1000KB) 1MB = 1000000字节

基本用法

1. 按行数分割文件
# 创建测试文件
seq 1 100 > numbers.txt

# 每10行分割一个文件
split -l 10 numbers.txt

# 查看生成的文件
ls x*
# 输出:xaa  xab  xac  xad  xae  xaf  xag  xah  xai  xaj

# 查看文件内容
head -5 xaa
# 输出:
# 1
# 2
# 3
# 4
# 5
2. 按文件大小分割
# 创建1MB的测试文件
dd if=/dev/zero of=largefile.bin bs=1M count=1

# 按100KB大小分割
split -b 100K largefile.bin

# 使用数字后缀
split -b 100K -d largefile.bin part_

# 查看文件大小
ls -lh part_* x*
# 输出:
# -rw-r--r-- 1 user user 100K Jan 10 10:00 part_00
# -rw-r--r-- 1 user user 100K Jan 10 10:00 part_01
# ...
# -rw-r--r-- 1 user user  24K Jan 10 10:00 part_10
3. 自定义输出文件名
# 指定前缀
split -l 1000 large_log.txt log_part_

# 使用数字后缀和自定义长度
split -l 500 -d -a 3 data.csv chunk_

# 添加文件扩展名
split -l 1000 -d --additional-suffix=.txt bigfile.txt part_

# 生成的文件:part_00.txt, part_01.txt, ...
4. 保持行完整的分割
# 按字节分割,但尽量保持行完整
split -C 1M logfile.txt

# 这对于文本文件特别有用,避免行被截断
split -C 100K --verbose data.txt chunk_
# 输出:
# 创建文件 'chunk_aa'
# 创建文件 'chunk_ab'
# ...

实际应用场景

场景1:日志文件分割
# 分割大型日志文件以便分析
split -l 10000 /var/log/app.log daily_log_

# 按日期分割(结合其他命令)
grep "2024-01-10" /var/log/app.log > day_log.txt
split -l 5000 -d day_log.txt hour_part_

# 为每个分片添加时间戳
split -l 10000 --verbose --additional-suffix=.log app.log app_part_
# 输出:
# 创建文件 'app_part_aa.log'
# 创建文件 'app_part_ab.log'
场景2:大数据集处理
# 将大型CSV文件分割为多个小文件以便并行处理
split -l 50000 -d large_dataset.csv dataset_chunk_

# 计算每个分片的行数
wc -l dataset_chunk_*

# 并行处理分片
for chunk in dataset_chunk_*; do
    process_data "$chunk" &
done
wait

echo "所有分片处理完成"
场景3:文件传输准备
# 将大文件分割为适合邮件附件的大小
split -b 10M large_video.mp4 video_part_

# 或者适合网络传输的大小
split -b 1G database_backup.sql db_backup_part_

# 上传分片文件
for part in video_part_*; do
    upload_to_cloud "$part"
done

# 下载后重新合并
cat video_part_* > large_video_restored.mp4
场景4:备份文件管理
#!/bin/bash
# 备份脚本:分割大型备份文件

BACKUP_FILE="backup_$(date +%Y%m%d).tar.gz"
SPLIT_PREFIX="backup_part_"
SPLIT_SIZE="100M"

echo "开始备份分割..."
tar -czf - /important/data | split -b $SPLIT_SIZE - $SPLIT_PREFIX

echo "备份分片信息:"
ls -lh ${SPLIT_PREFIX}*
echo "分片数量:$(ls ${SPLIT_PREFIX}* | wc -l)"

# 恢复时使用:
# cat ${SPLIT_PREFIX}* | tar -xzf -

高级用法

1. 等量分割
# 将文件分割成指定数量的等大部分
split -n 5 large_file.txt

# 按字节数等分(近似)
file_size=$(stat -c%s large_file.txt)
split_count=4
split_size=$((file_size / split_count))
split -b ${split_size} large_file.txt part_
2. 使用过滤器
# 分割时对每个分片进行压缩
split -l 1000 --filter='gzip > $FILE.gz' data.txt compressed_part_

# 分割时计算每个分片的MD5
split -b 1M --filter='md5sum > $FILE.md5' bigfile.bin part_

# 查看生成的MD5文件
cat part_aa.md5
3. 从标准输入读取
# 从管道读取数据并分割
cat large_file.txt | split -l 1000 - stream_part_

# 结合其他命令
find /var/log -name "*.log" -exec cat {} \; | split -l 5000 - all_logs_part_

# 实时分割数据流
tail -f /var/log/app.log | split -l 100 -d -a 4 - live_log_part_
4. 复杂分割策略
#!/bin/bash
# 智能文件分割脚本

FILE=$1
MAX_SIZE="10M"  # 每个分片的最大大小
MIN_LINES=1000  # 每个分片的最小行数

if [ ! -f "$FILE" ]; then
    echo "文件不存在: $FILE"
    exit 1
fi

file_size=$(stat -c%s "$FILE")
file_lines=$(wc -l < "$FILE")

echo "文件信息:"
echo "  大小: $(numfmt --to=iec $file_size)"
echo "  行数: $file_lines"

# 计算最佳分割策略
if [ $file_size -gt $((100 * 1024 * 1024)) ]; then
    # 大文件:按大小分割
    echo "按大小分割 (每个分片 $MAX_SIZE)..."
    split -b $MAX_SIZE -d --verbose "$FILE" "${FILE}_part_"
else
    # 小文件:按行数分割,确保每个分片至少有MIN_LINES行
    target_parts=$((file_lines / MIN_LINES))
    target_parts=$((target_parts > 0 ? target_parts : 1))
    lines_per_part=$((file_lines / target_parts))

    echo "按行数分割 ($lines_per_part 行每个分片)..."
    split -l $lines_per_part -d --verbose "$FILE" "${FILE}_part_"
fi

echo "分割完成"

文件合并方法

分割后的文件可以使用多种方法重新合并:

1. 使用cat命令合并
# 合并字母后缀的文件
cat xaa xab xac > original_file.txt

# 合并数字后缀的文件(按数字顺序)
cat part_00 part_01 part_02 > original_file.txt

# 使用通配符按顺序合并
cat part_* > original_file.txt
2. 处理特殊情况的合并
# 确保按正确顺序合并
ls part_* | sort -V | xargs cat > original_file.txt

# 或者使用数字排序
ls part_* | sort -t_ -k2 -n | xargs cat > original_file.txt

# 验证合并后的文件完整性
original_md5=$(md5sum original_file.txt | cut -d' ' -f1)
recovered_md5=$(cat part_* | md5sum | cut -d' ' -f1)

if [ "$original_md5" = "$recovered_md5" ]; then
    echo "文件合并成功,MD5校验通过"
else
    echo "文件合并失败,MD5不匹配"
fi

与其他命令的比较

命令 功能 适用场景
split 文件分割 将大文件分割为多个小文件
csplit 按上下文分割 基于模式或内容分割文件
dd 数据复制和转换 精确控制字节级别的文件操作
head/tail 提取文件部分内容 获取文件开头或结尾部分
sed 流编辑器 基于行的文本处理和提取

实用技巧

  • 使用 -d 选项生成数字后缀,便于排序和合并
  • 使用 --verbose 查看分割过程,特别是处理大文件时
  • 使用 -C 而不是 -b 来分割文本文件,避免行被截断
  • 结合 --filter 可以在分割时直接处理每个分片
  • 使用 split -n 可以确保所有分片大小相近
  • 在脚本中使用 split 时,总是检查源文件是否存在
  • 合并文件时使用 sort -V 确保正确的文件顺序

注意事项

  • 默认情况下,split 使用字母后缀(xaa, xab, ...),最多支持676个文件
  • 使用 -a 选项可以增加后缀长度以支持更多文件
  • 分割二进制文件时,使用 -b 选项按字节分割
  • 分割后的文件会覆盖已存在的同名文件,使用时要注意
  • 在低磁盘空间环境下分割大文件时要小心
  • 合并文件时需要确保正确的文件顺序
  • split 不会保留文件的特殊属性(如权限、时间戳等)