如何在UNIX中将前1亿条记录(或)1GB文件从.txt文件移动到新文件

zmeyuzjn  于 2023-06-29  发布在  Unix
关注(0)|答案(2)|浏览(166)

我在努力
输入文件:input.txt文件中的行数:21194896560文件大小~ 230 GB系统可用空间为30 GB。
我在努力
1.移动顶部1GB文件从input.txt文件到first1gb.txt一旦我继续此文件,并希望提取第二个文件
1.将第二个1GB文件从input.txt文件移动到second1gb.txt
我正在尝试这个命令

split -b 1g myfile segment

有了这个,我能够提取第一个1GB文件,但无法从输入文件中删除1GB数据,也无法获得另一个1GB文件。
有什么帮助吗?

xzv2uavs

xzv2uavs1#

未经测试的东西:
将input.txt中的前1GB复制到first1gb.txt文件中:

dd if=input.txt of=first1gb.txt bs=1M count=1024

将2GB的数据从文件末尾移动到文件开头。左移文件1GB。在C中的伪代码memmove(input.txt, input.txt+1GB, sizeof(input.txt)-1GB) .

dd if=input.txt of=input.txt conv=notrunc bs=1M skip=1024

删除文件的最后1GB:

truncate -s -1G input.txt

然后重复下一个1GB。
为了省略左移和简化截断,如果你想处理整个文件,用一些“数学”知道文件的大小,你可以从结尾开始提取块。这将大大增加执行时间,因为大文件的左移将永远持续下去。通过从末尾开始,您将只在总复制文件字节一次块后块。
如何移动前1亿条记录
类似地,提取前1亿行。

head -n $((100*1000*1000*1000)) input.txt > first100m.txt

左移文件100百万行。

dd if=input.txt of=input.txt bs=1M conv=notrunc iflag=skip_bytes skip=$(stat -c %s first100m.txt)

截断多余的字节:

truncate -s -$(stat -c %s first100m.txt) input.txt

一个包含10行的文件的示例,一次提取两行:

#!/bin/bash
set -euo pipefail
rm -f *.txt
seq 10 > input.txt
lines=2
for ((i = 0; 1; ++i)); do
        if [[ ! -s input.txt ]]; then
                break
        fi
        head -n "$lines" input.txt > "output_$i.txt"
        size=$(stat -c %s "output_$i.txt")
        dd of=input.txt if=input.txt bs=1M conv=notrunc iflag=skip_bytes skip="$skip"
        truncate -s -"$skip" input.txt
done
tail -n +1 *.txt

脚本输出:

==> input.txt <==

==> output_0.txt <==
1
2

==> output_1.txt <==
3
4

==> output_2.txt <==
5
6

==> output_3.txt <==
7
8

==> output_4.txt <==
9
10

下面是具有相同结果的代码,但是从文件的末尾提取。缺少左移文件的dd

#!/bin/bash
set -euo pipefail
rm -f *.txt
seq 10 > input.txt
lines=2
inputlines=$(wc -l < input.txt)
chunks=$(( inputlines / lines ))
for ((i = chunks - 1; i >= 0; --i)); do
        if [[ ! -s input.txt ]]; then
                break
        fi
        tail -n "$lines" input.txt > "output_$i.txt"
        size="$(stat -c %s "output_$i.txt")"
        truncate -s -"$size" input.txt
done
tail -n +1 *.txt
j13ufse2

j13ufse22#

这可能对你有用(GNU Parallel):

cat bigFile | parallel -j 1 -pipe -n 1G 'cat >1GFile; processFile <1GFile' && rm 1GFile

使用并行顺序将每个进程分成1G行,然后使用processFile读取这些行,最后一旦bigFile结束,清理1GFile
注意:如果记录是固定长度的,可以更快,请参阅此处

相关问题