gpt4 book ai didi

linux - 如何使用 linux 命令交换重复格式数据 block 内的数字?

转载 作者:太空宇宙 更新时间:2023-11-04 10:54:29 26 4
gpt4 key购买 nike

我有一个巨大的数据文件,我希望在下面的格式文件中只交换一些第 2 列的数字。该文件有 25,000,000 个数据集,每个数据集有 8768 行。

%% 已编辑:更短的 10 行示例。带来不便敬请谅解。这是典型的一个数据 block 。

# 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 个尾随行,每个数据 block 总共有 8776 行。那一行尾部只包含一个“#”。

我只想交换第 2 列中的一些数字。首先,我要替换

1, 9, 10, 11 => 666
2, 6, 7, 8 => 333
3, 4, 5 => 222

第二列,然后,

666 => 6
333 => 3
222 => 2

第 2 列。我希望对所有重复数据集进行此替换。

我用python试过,但是数据太大,所以会出现内存错误。如何使用 sed 或 awk 或 cat 命令等 linux 命令执行此交换?

谢谢

最好的,

最佳答案

这可能对您有用,但您必须使用 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 将第一个数字模式的第一次出现替换为本身与一个空格和从 swap(操作)返回。在这种情况下,我使用 gensub 的替换文本来保留第一列数据。第二列使用 $2 的字段数据标识符传递给 swap。使用 gensub 应该保留数据行的格式。
  • 47 - 计算结果为 true 的表达式提供打印 $0 的默认操作,对于数据行可能已修改。任何不是“数据”的行都将在此处打印出来,无需修改。

提供的数据并没有展示所有的情况,所以我自己做了一个测试文件:

# 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

运行可执行文件 awk(如 ./script.awk data)给出以下输出:

# 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

这对我来说看起来不错,但我不是拥有 2500 万个数据集的人。

您肯定也想首先在较小的数据样本(前几个数据集?)上尝试此操作,然后将 stdout 重定向到临时文件,例如:

head -n 26328 data | ./script.awk - > tempfile

您可以在此处了解有关此脚本中使用的元素的更多信息:

当然,您应该花一些时间在 Stack Overflow 上查看与 awk 相关的问题和答案;)

关于linux - 如何使用 linux 命令交换重复格式数据 block 内的数字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29378136/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com