Bootstrap

【shell】将txt文件拆成n个,文本均匀按行分布

#!/bin/bash  
  
# 原始文件名  
source_file="/home/part.txt"

# 目标文件存放目录
target_dir="/home"

# 想要的近似文件数量
desired_files=2  # 请将n替换为具体的数字,比如100

# 确保目标目录存在
mkdir -p "$target_dir"

# 计算原始文件的总行数(这可能需要一些时间,因为文件很大)
total_lines=$(wc -l < "$source_file")

# 计算每个文件应包含的行数(向上取整)
# 注意:如果total_lines不能被desired_files整除,最后一个文件可能会少几行
lines_per_file=$((total_lines / desired_files + (total_lines % desired_files > 0)))

# 初始化文件计数器
file_counter=1

# 当前文件已写入的行数
current_lines=0

# 使用awk来拆分文件
awk -v lines="$lines_per_file" -v dir="$target_dir" '
{
    # 构造文件名
    file_name = sprintf("%s/part%03d.txt", dir, file_counter)

    # 打印当前行到文件
    print > file_name

    # 更新当前文件已写入的行数
    current_lines++

    # 如果当前文件已达到行数限制,准备下一个文件
    if (current_lines >= lines) {
        file_counter++
        current_lines = 0
    }
}
END {
    # 确保关闭最后一个文件(尽管awk在结束时会自动关闭文件)
    # 这里主要是为了让脚本逻辑更清晰
    # 在实际情况下,这行可能是多余的
}
' "$source_file"

# 输出结果信息
actual_files=$((file_counter))
echo "File split into $actual_files parts in $target_dir, with approximately $lines_per_file lines per part."

注意:

  1. 请将脚本中的/path/to/your/large_file.txt替换为你的原始文件的实际路径。
  2. 请将脚本中的n替换为你希望的文件数量的具体值。但是,请注意,由于原始文件的行数可能无法被desired_files整除,因此实际生成的文件数量可能会略有不同。
  3. 这个脚本使用awk来逐行读取并写入文件,效率相对较高,特别是对于大文件。但是,由于它需要先读取整个文件来计算总行数,因此在开始拆分之前可能会有一些延迟。
  4. 文件名采用partXXX.txt的格式,其中XXX是三位数的序号。这有助于在生成大量文件时保持文件名的整洁性。
  5. 如果你的系统中有足够的内存来处理这个大文件,并且你希望进一步提高速度,可以考虑使用更专业的文本处理工具或编程语言(如Python)来实现拆分功能,这些工具可能提供了更优化的内存管理和并行处理能力。但是,对于大多数基本需求来说,上述Shell脚本应该已经足够高效。
;