如何使用 linux 命令交换重复格式数据块内的数字?
How can I swap numbers inside data block of repeating format using linux commands?
我有一个巨大的数据文件,我希望只交换一些第2列的数字,在下面的格式文件中。该文件有 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 条重复的 header 行,数据集末尾有 1 条尾随行。那些 header 和结尾的行都是从 # 开始的。因此,数据将有 7 header 行,8768 条数据行和 1 条尾随行,每个数据块总共有 8776 行。那一行尾部只包含一个“#”。
我只想交换第 2 列中的一些数字。首先,我想替换
1, 9, 10, 11 => 666
2, 6, 7, 8 => 333
3, 4, 5 => 222
第 2 列,然后
666 => 6
333 => 3
222 => 2
第 2 列。我希望对所有重复数据集进行此替换。
我用python试过这个,但是数据太大,所以会出现内存错误。如何使用 sed 或 awk 或 cat 命令等 linux 命令执行此交换?
谢谢
最佳,
这可能对你有用,但你必须使用 GNU awk,因为它使用 gensub
命令和 [=15=]
重新分配。
将以下内容放入可执行的 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]+ )/ { [=10=] = gensub( /^( [0-9]+)( [0-9]+)/, "\1 " swap(), 1 ) }
47 # print the line
细目如下:
BEGIN
- 使用新值的映射设置数组 a
。
- 创建一个用户定义的函数
swap
来为 a
数组的第二列或值本身提供值。 c2
元素被传入,而 val
元素是局部变量(因为没有传入第二个参数)。
- 当一行以 space 开头,后跟数字和 space(模式)时,然后使用
gensub
将第一个数字模式的第一次出现替换为本身与 space 和 swap
(操作)中的 return 连接。在这种情况下,我使用 gensub 的替换文本来保留第一列数据。第二列使用 </code> 的字段数据标识符传递给 <code>swap
。使用 gensub
应保留数据行的格式。
47
- 计算结果为 true 的表达式提供打印 [=15=]
的默认操作,对于数据行可能已被修改。任何不是 "data" 的行都将在此处打印出来 w/o 修改。
提供的数据并没有显示所有情况,所以我自己制作了测试文件:
# 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 相关的问题和答案;)
我有一个巨大的数据文件,我希望只交换一些第2列的数字,在下面的格式文件中。该文件有 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 条重复的 header 行,数据集末尾有 1 条尾随行。那些 header 和结尾的行都是从 # 开始的。因此,数据将有 7 header 行,8768 条数据行和 1 条尾随行,每个数据块总共有 8776 行。那一行尾部只包含一个“#”。
我只想交换第 2 列中的一些数字。首先,我想替换
1, 9, 10, 11 => 666
2, 6, 7, 8 => 333
3, 4, 5 => 222
第 2 列,然后
666 => 6
333 => 3
222 => 2
第 2 列。我希望对所有重复数据集进行此替换。
我用python试过这个,但是数据太大,所以会出现内存错误。如何使用 sed 或 awk 或 cat 命令等 linux 命令执行此交换?
谢谢
最佳,
这可能对你有用,但你必须使用 GNU awk,因为它使用 gensub
命令和 [=15=]
重新分配。
将以下内容放入可执行的 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]+ )/ { [=10=] = gensub( /^( [0-9]+)( [0-9]+)/, "\1 " swap(), 1 ) }
47 # print the line
细目如下:
BEGIN
- 使用新值的映射设置数组a
。- 创建一个用户定义的函数
swap
来为a
数组的第二列或值本身提供值。c2
元素被传入,而val
元素是局部变量(因为没有传入第二个参数)。 - 当一行以 space 开头,后跟数字和 space(模式)时,然后使用
gensub
将第一个数字模式的第一次出现替换为本身与 space 和swap
(操作)中的 return 连接。在这种情况下,我使用 gensub 的替换文本来保留第一列数据。第二列使用</code> 的字段数据标识符传递给 <code>swap
。使用gensub
应保留数据行的格式。 47
- 计算结果为 true 的表达式提供打印[=15=]
的默认操作,对于数据行可能已被修改。任何不是 "data" 的行都将在此处打印出来 w/o 修改。
提供的数据并没有显示所有情况,所以我自己制作了测试文件:
# 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 相关的问题和答案;)