Keuin 最近的时间轴更新
Keuin

Keuin

V2EX 第 211862 号会员,加入于 2017-01-22 19:01:13 +08:00
今日活跃度排名 11015
Keuin 最近回复了
118 天前
回复了 TMMXA 创建的主题 NAS 给实验室配了一台公用 nas 想让各位大佬出出主意
不要自己意淫需求,你这里大部分都是伪需求
买个白群或者威联通,插几块新盘,解决,不要搞这些图吧方案,公共资产不是你的 homelab
124 天前
回复了 desGalaxy 创建的主题 Windows Crowdstrike crash 是由空指针解引用导致
Rust 也不能保证不会出 bug ,解决 bug 的应该是流程和规范,而非语言
仅理论分析一下,raid5 每个盘存储的都是奇偶校验信息,没有存原始数据的盘,因此备份和重建都需要读所有盘的所有内容。丢数据是坏了两个盘,现在已经坏了一个,备份跟重建都是要读所有盘,因此没有区别,怎么样都可以。
@wxf666 自己研究一下吧,昨天的楼被删了,我懒得再写一遍了,只需要假定 csv 列数固定,不需要用到 cut 。如果假定不了,简便起见,需要找一个输入里面没有的分隔符。
写入量的话,我在原 po 主帖子里分析过,不过那里把加行号的中间结果也全部存下来了,所以当时给的磁盘用量是 3*6TB 。如果都用流式传递中间结果的话,两个 sort 需要有 2*6TB 的临时空间。
@wxf666 昨天写的马虎,忘记顺序这个要求了,我其实又回复了一次来 update ,不过看起来楼被 v 站吞了。保序的方案是用 sort -u -k1,4 来只按原内容排序并去重,最后 sed 去掉行号,最最后的 uniq 去掉即可
@Keuin 没有保序,bugfix 一下。假设 csv 有 4 列,把 sort 替换成`sort -u -t, -k1,4 | sort -t, -k5`,把结尾的 uniq 删掉,变成:

```shell
awk '{print $0","NR}' input | sort -u -t, -k1,4 | sort -t, -k5 | sed -E 's/,[0-9]+$//' | uniq
```
不能假设列数的话,受这几个 shell 工具的限制,需要换一个没有出现过的字符做分隔符
```shell
awk '{print $0","NR}' input.csv | sort | sed -E 's/,[0-9]+$//' | uniq
```

Example usage:

```
$ cat input
1,2,3,4
2,3,4,5
3,4,5,6
4,5,6,7
2,3,4,5
1,2,3,4
5,6,7,8
$ awk '{print $0","NR}' input
1,2,3,4,1
2,3,4,5,2
3,4,5,6,3
4,5,6,7,4
2,3,4,5,5
1,2,3,4,6
5,6,7,8,7
$ awk '{print $0","NR}' input | sort
1,2,3,4,1
1,2,3,4,6
2,3,4,5,2
2,3,4,5,5
3,4,5,6,3
4,5,6,7,4
5,6,7,8,7
$ awk '{print $0","NR}' input | sort | sed -E 's/,[0-9]+$//'
1,2,3,4
1,2,3,4
2,3,4,5
2,3,4,5
3,4,5,6
4,5,6,7
5,6,7,8
$ awk '{print $0","NR}' input | sort | sed -E 's/,[0-9]+$//' | uniq
1,2,3,4
2,3,4,5
3,4,5,6
4,5,6,7
5,6,7,8
```

不管你的电脑内存是 1T 还是 1G ,都可以正确运行并得到相同输出,因为 sort 命令用的是归并排序,是外存算法。如果你要限制用到的内存大小,把 sort 改成 sort --buffer-size=100M ,即可限制只用 100M 内存,其他命令都是行缓存算法,只会保存当前行在内存里,也就是说,最大内存用量是 max(100M, max_line_size_bytes)
一行 shell 的事被你搞得这么复杂,6TB 可以存内存里,6PB 呢?
看不下去了,这个源码也不愿意给,我直接给出结论:
```shell
awk '{print $0","NR}' input.csv | sort | sed -E 's/,[0-9]+$//' | uniq
```
其中 input.csv 替换成你的输入文件,结果将出现在 stdout ,如果要存到文件,自己重定向一下即可。
运行实例:
```
$ cat input
1,2,3,4
2,3,4,5
3,4,5,6
4,5,6,7
2,3,4,5
1,2,3,4
5,6,7,8
$ awk '{print $0","NR}' input
1,2,3,4,1
2,3,4,5,2
3,4,5,6,3
4,5,6,7,4
2,3,4,5,5
1,2,3,4,6
5,6,7,8,7
$ awk '{print $0","NR}' input | sort
1,2,3,4,1
1,2,3,4,6
2,3,4,5,2
2,3,4,5,5
3,4,5,6,3
4,5,6,7,4
5,6,7,8,7
$ awk '{print $0","NR}' input | sort | sed -E 's/,[0-9]+$//'
1,2,3,4
1,2,3,4
2,3,4,5
2,3,4,5
3,4,5,6
4,5,6,7
5,6,7,8
$ awk '{print $0","NR}' input | sort | sed -E 's/,[0-9]+$//' | uniq
1,2,3,4
2,3,4,5
3,4,5,6
4,5,6,7
5,6,7,8
```

不管你的电脑内存是 1T 还是 1G ,都可以正确运行并得到相同输出,因为 sort 命令用的是归并排序,是外存算法。如果你要限制用到的内存大小,把 sort 改成 sort --buffer-size=100M ,即可限制只用 100M 内存,其他命令都是行缓存算法,只会保存当前行在内存里,也就是说,最大内存用量是 max(100M, max_line_size_bytes)
@Keuin 最后还差一步,按行号升序排序,重新排序回原来的顺序,最大额外磁盘空间不变
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   928 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 11ms · UTC 21:20 · PVG 05:20 · LAX 13:20 · JFK 16:20
Developed with CodeLauncher
♥ Do have faith in what you're doing.