我的文件系统已满,并且有几个非常大的文件需要清理split
(以便其中一些可以存档tar
,其他可以检查)。有没有办法split
实现“就地”行为?例如,我需要split -4 file
写出四个新文件,而不使用文件系统上的任何额外空间。
有没有办法做到这一点?
答案1
不可能准确地在原地完成这件事。
也许您可以使用这个答案中建议的解决方案: 就地提取 tar 存档
archive="archive.tar"
chunkprefix="chunk_"
# 1-Mb chunks :
chunksize=1048576
totalsize=$(wc -c "$archive" | cut -d ' ' -f 1)
currentchunk=$(((totalsize-1)/chunksize))
while [ $currentchunk -ge 0 ]; do
# Print current chunk number, so we know it is still running.
echo -n "$currentchunk "
offset=$((currentchunk*chunksize))
# Copy end of $archive to new file
tail -c +$((offset+1)) "$archive" > "$chunkprefix$currentchunk"
# Chop end of $archive
truncate -s $offset "$archive"
currentchunk=$((currentchunk-1))
done
它的作用是将文件的一部分复制到另一个文件中,然后立即从原始文件中将其删除。
这样您只需要 1MB 的可用磁盘空间(假设您分成 1MB)。
编辑:如果您没有可用磁盘空间,但有足够的 RAM,您可能能够创建一个 ramdisk 并将每个块存储在那里,同时删除原始块。不过还没有测试过:
ramsize=4096
rammount=/ramdisk
archive="archive.tar"
chunkprefix="$rammount/chunk_"
# 1-Mb chunks :
chunksize=1048576
mkdir $rammount
mkfs -q /dev/ram1 $ramsize
mount /dev/ram1 $rammount
totalsize=$(wc -c "$archive" | cut -d ' ' -f 1)
currentchunk=$(((totalsize-1)/chunksize))
while [ $currentchunk -ge 0 ]; do
# Print current chunk number, so we know it is still running.
echo -n "$currentchunk "
offset=$((currentchunk*chunksize))
# Copy end of $archive to new file
tail -c +$((offset+1)) "$archive" > "$chunkprefix$currentchunk"
# Chop end of $archive
truncate -s $offset "$archive"
# copy the chunk on disk
cp "$chunkprefix$currentchunk" .
currentchunk=$((currentchunk-1))
done
它与脚本完全相同,只是它首先创建并安装一个 4MB 的 ramdisk,并将每个块临时存储在那里,直到通过截断原始文件释放空间。
答案2
您可以尝试使用映射到内存的文件系统空间 (tmpfs) 作为新文件的交换空间,直到原始文件被删除,从而为您提供将新文件移回磁盘的空间。有时这是 /dev/shm,或者只是 /tmp 或 /var/tmp,具体取决于您的 Linux 发行版。mount 的输出可能会向您指示安装在 tmpfs 上的文件系统空间
例如,在我手边的一台服务器上,mount 显示以下内容:
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
并df -h
告诉我关于/dev/shm
tmpfs 249M 0 249M 0% /dev/shm
注意:如果该空间过满,则会影响需要内存才能正常运行的其他进程,会导致交换到 HDD 上的交换空间,这会增加 CPU 上下文交换时间,因为当该进程获得 CPU 周期时,它必须将这些内容从交换中加载回内存。
答案3
我认为这是不可能的,因为一个文件需要一个或多个块,因此如果您不想在块边界处分割,则需要移动文件的其余部分,以便它从块的开头开始。
不过,你可以使用dd
到读文件的一部分-存档或检查。