我有一个庞大的数据文件,我希望只在以下格式文件中交换一些第二列的数字。该文件有25,000,000个数据集,每个数据集8768行。
%%已编辑:较短的10行示例。抱歉给你带来不便。这是典型的一个数据块。
# Dataset 1
#
# Number of lines 10
#
# header lines
5 11 3 10 120 90 0 0.952 0.881 0.898 2.744 0.034 0.030
10 12 3 5 125 112 0 0.952 0.897 0.905 2.775 0.026 0.030
50 10 3 48 129 120 0 1.061 0.977 0.965 3.063 0.001 0.026
120 2 4 5 50 186 193 0 0.881 0.965 0.899 0.917 3.669 0.000 -0.005
125 3 4 10 43 186 183 0 0.897 0.945 0.910 0.883 3.641 0.000 0.003
186 5 4 120 125 249 280 0 0.899 0.910 0.931 0.961 3.727 0.000 -0.001
193 6 4 120 275 118 268 0 0.917 0.895 0.897 0.937 3.799 0.000 0.023
201 8 4 278 129 131 280 0 0.921 0.837 0.870 0.934 3.572 0.000 0.008
249 9 4 186 355 179 317 0 0.931 0.844 0.907 0.928 3.615 0.000 0.008
280 10 4 186 201 340 359 0 0.961 0.934 0.904 0.898 3.700 0.000 0.033
#
# Dataset 1
#
# Number of lines 10
...
如您所见,头部有7条重复的标题行,数据集末尾有1条尾随行。那些标题和尾随行都是从#开始的。结果,数据将具有7个标题行,8768个数据行和1个尾随行,每个数据块总共8776行。那一条尾随行只包含sinlge'#'。
我想只在第二列中交换一些数字。首先,我想替换
1, 9, 10, 11 => 666
2, 6, 7, 8 => 333
3, 4, 5 => 222
的第二列,然后,
666 => 6
333 => 3
222 => 2
的第二栏。我希望对所有重复数据集进行替换。
我用python尝试过这个,但是数据太大了,所以它会导致内存错误。如何使用sed或awk或cat命令等linux命令执行此交换?
谢谢
最好,
答案 0 :(得分:1)
这可能适合您,但您必须使用GNU awk,因为它使用gensub
命令和$0
重新分配。
将以下内容放入可执行的awk文件(如script.awk
):
#!/usr/bin/awk -f
BEGIN {
a[1] = a[9] = a[10] = a[11] = 6
a[2] = a[6] = a[7] = a[8] = 3
a[3] = a[4] = a[5] = 2
}
function swap( c2, val ) {
val = a[c2]
return( val=="" ? c2 : val )
}
/^( [0-9]+ )/ { $0 = gensub( /^( [0-9]+)( [0-9]+)/, "\\1 " swap($2), 1 ) }
47 # print the line
以下是细分:
BEGIN
- 设置一个数组a
,其中包含新值的映射。swap
,以便为a
数组中的第二列或值本身提供值。传入c2
元素,而val
元素是局部变量(因为没有传入第二个参数)。gensub
替换第一个数字模式的第一个出现,其自身与空格连接并从{返回{1}}(行动)。在这种情况下,我使用gensub的替换文本来保留第一列数据。使用swap
的字段数据标识符将第二列传递给swap
。使用$2
应保留数据行的格式。gensub
- 计算结果为true的表达式提供打印47
的默认操作,该操作可能已修改数据行。任何不是&#t;#34;数据"将在没有修改的情况下打印出来。提供的数据并未显示所有情况,因此我编写了自己的测试文件:
$0
运行可执行文件awk(如# 2 skip me
9 2 not going to process me
1 1 don't change the for matting
2 2 4 23242.223 data
3 3 data that's formatted
4 4 7 that's formatted
5 5 data that's formatted
6 6 data that's formatted
7 7 data that's formatted
8 8 data that's formatted
9 9 data that's formatted
10 10 data that's formatted
11 11 data that's formatted
12 12 data that's formatted
13 13 data that's formatted
14 s data that's formatted
# some other data
)会给出以下输出:
./script.awk data
对我而言看起来不错,但我不是拥有2500万个数据集的人。
您还绝对希望首先在较小的数据样本(前几个数据集?)上尝试此操作,并将stdout重定向到临时文件,可能是这样的:
# 2 skip me
9 2 not going to process me
1 6 don't change the for matting
2 3 4 23242.223 data
3 2 data that's formatted
4 2 7 that's formatted
5 2 data that's formatted
6 3 data that's formatted
7 3 data that's formatted
8 3 data that's formatted
9 6 data that's formatted
10 6 data that's formatted
11 6 data that's formatted
12 12 data that's formatted
13 13 data that's formatted
14 s data that's formatted
# some other data
您可以在此处详细了解此脚本中使用的元素:
当然,你应该花一些时间在Stack Overflow上查看与awk相关的问题和答案;)