使用 GNU Parallel 打印行列表中行号之间的行,并将每个实例保存在单独的文件中
Print lines between line numbers from a line list and save every instance in separate file using GNU Parallel
我有一个文件,例如 "Line_File",其中包含行开始和结束编号以及文件 ID 的列表:
F_a 1 108
F_b 109 1210
F_c 131 1190
我有另一个文件 "Data_File",我需要从中获取从 Line_File.
获取的行号之间的所有行
sed中的命令:
'sed -n '1,108p' Data_File > F_a.txt
可以完成这项工作,但我需要对 Line_File 的第 2 列和第 3 列中的所有值执行此操作,并使用 Line_File 的第 1 列中提到的文件名保存它。
如果 $1、$2 和 $3 是 Line_File 的三个列,那么我正在寻找类似
的命令
'sed -n ',p' Data_File > .txt
我可以 运行 使用 Bash 循环,但对于一个非常大的文件,比如 40GB,这会非常慢。
我特别想这样做,因为我正在尝试使用 GNU Parallel 使其更快,并且基于行号的切片将使输出不重叠。我正在尝试执行这样的命令
cat Data_File | parallel -j24 --pipe --block 1000M --cat LC_ALL=C sed -n ',p' > .txt
但我无法正确使用列赋值 $1、$2 和 $3。
我尝试了以下命令:
awk '{system("sed -n \""",""p\" Data_File > "NR)}' Line_File
但是没用。知道我哪里出错了吗?
P.S 如果我的问题不清楚,请指出我还应该分享什么。
您可以将 xargs
与 -P
(并行)选项一起使用:
xargs -P 8 -L 1 bash -c 'sed -n ",p" Data_File > .txt' _ < Line_File
解释:
- 此
xargs
命令使用 <
将 Line_File
作为输入
-P 8
选项允许它 运行 最多并行 8 个进程
-L 1
使 xargs
一次处理一行
bash -c ...
forks bash
输入文件中的每一行
_
在 <
之前将 _
作为 [=25=]
传递,并将每个输入行中剩余的 3 列作为 , ,
$3`
sed -n
运行s sed
命令每行组成一个命令行
或者您可以这样使用 gnu parallel
:
parallel --colsep '[[:blank:]]' "sed -n '{2},{3}p' Data_File > {1}.txt" :::: Line_File
awk
救援!
这只扫描一次数据文件
$ awk 'NR==FNR {k=; s[k]=; e[k]=; next}
{for(k in s) if(FNR>=s[k] && FNR<=e[k]) print > (k".txt")}' lines data
这可能对您有用(GNU 并行和 sed):
parallel --dry-run -a lineFile -C' ' "sed -n '{2},{3}p' dataFile > {1}'
这使用列分隔符 -C ' '
并将其设置为 space,然后将 lineFile 的前 3 个字段设置为 {1}
、{2}
和 {3}
。 --dry-run
选项允许您检查在 运行 之前并行生成的命令是否真实。一旦命令看起来正确,请删除 --dry-run
选项。
您可能不会 CPU 受到约束。您的磁盘更有可能成为限制因素。为避免一遍又一遍地读取数据文件,您应该运行 并行处理尽可能多的作业。这样缓存将帮助你:
cat Line_file |
parallel -j0 --colsep ' ' sed -n {2},{3}p Data_File \> {1}.txt
我有一个文件,例如 "Line_File",其中包含行开始和结束编号以及文件 ID 的列表:
F_a 1 108
F_b 109 1210
F_c 131 1190
我有另一个文件 "Data_File",我需要从中获取从 Line_File.
获取的行号之间的所有行sed中的命令:
'sed -n '1,108p' Data_File > F_a.txt
可以完成这项工作,但我需要对 Line_File 的第 2 列和第 3 列中的所有值执行此操作,并使用 Line_File 的第 1 列中提到的文件名保存它。
如果 $1、$2 和 $3 是 Line_File 的三个列,那么我正在寻找类似
的命令'sed -n ',p' Data_File > .txt
我可以 运行 使用 Bash 循环,但对于一个非常大的文件,比如 40GB,这会非常慢。
我特别想这样做,因为我正在尝试使用 GNU Parallel 使其更快,并且基于行号的切片将使输出不重叠。我正在尝试执行这样的命令
cat Data_File | parallel -j24 --pipe --block 1000M --cat LC_ALL=C sed -n ',p' > .txt
但我无法正确使用列赋值 $1、$2 和 $3。
我尝试了以下命令:
awk '{system("sed -n \""",""p\" Data_File > "NR)}' Line_File
但是没用。知道我哪里出错了吗?
P.S 如果我的问题不清楚,请指出我还应该分享什么。
您可以将 xargs
与 -P
(并行)选项一起使用:
xargs -P 8 -L 1 bash -c 'sed -n ",p" Data_File > .txt' _ < Line_File
解释:
- 此
xargs
命令使用<
将 -P 8
选项允许它 运行 最多并行 8 个进程-L 1
使xargs
一次处理一行bash -c ...
forksbash
输入文件中的每一行_
在<
之前将_
作为[=25=]
传递,并将每个输入行中剩余的 3 列作为, ,
$3`sed -n
运行ssed
命令每行组成一个命令行
Line_File
作为输入
或者您可以这样使用 gnu parallel
:
parallel --colsep '[[:blank:]]' "sed -n '{2},{3}p' Data_File > {1}.txt" :::: Line_File
awk
救援!
这只扫描一次数据文件
$ awk 'NR==FNR {k=; s[k]=; e[k]=; next}
{for(k in s) if(FNR>=s[k] && FNR<=e[k]) print > (k".txt")}' lines data
这可能对您有用(GNU 并行和 sed):
parallel --dry-run -a lineFile -C' ' "sed -n '{2},{3}p' dataFile > {1}'
这使用列分隔符 -C ' '
并将其设置为 space,然后将 lineFile 的前 3 个字段设置为 {1}
、{2}
和 {3}
。 --dry-run
选项允许您检查在 运行 之前并行生成的命令是否真实。一旦命令看起来正确,请删除 --dry-run
选项。
您可能不会 CPU 受到约束。您的磁盘更有可能成为限制因素。为避免一遍又一遍地读取数据文件,您应该运行 并行处理尽可能多的作业。这样缓存将帮助你:
cat Line_file |
parallel -j0 --colsep ' ' sed -n {2},{3}p Data_File \> {1}.txt