使用 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

Check parallel examples from official doc

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