【问题标题】:How to split an interleaved text file using bash commands如何使用 bash 命令拆分交错的文本文件
【发布时间】:2019-01-31 22:13:42
【问题描述】:

我想将一个文本文件拆分为多个单个文件。由于该命令将在远程集群上执行,因此我正在为该作业寻找简单的 bash 命令。

文件结构由一个标头组成,后跟隔行扫描的数据。 标题是一行,其中包含测量数据的探针数 (N),N 行是探针的位置(坐标)。

然后,在每次调用时,都会在 N 行中附加测量数据(时间、速度 (x,y,z)、压力、温度)。

整体结构:

N
x1 y1 z1
x2 y2 z2
x3 y3 z3
...
xN yN zN
time1 vx1 vy1 vz1 pr1 tmp1
time1 vx2 vy2 vz2 pr2 tmp2
time1 vx3 vy3 vz3 pr3 tmp3
...
time1 vxN vyN vzN prN tmpN
time2 vx1 vy1 vz1 pr1 tmp1
time2 vx2 vy2 vz2 pr2 tmp2
time2 vx3 vy3 vz3 pr3 tmp3
...
time2 vxN vyN vzN prN tmpN
time3 vx1 vy1 vz1 pr1 tmp1
time3 vx2 vy2 vz2 pr2 tmp2
....

它会一直持续到运行时结束。

我想将此文件拆分为 N 个单独的文本文件,每个探针一个,如下所示:

time1 vx1 vy1 vz1 pr1 tmp1
time2 vx1 vy1 vz1 pr1 tmp1
time3 vx1 vy1 vz1 pr1 tmp1
time4 vx1 vy1 vz1 pr1 tmp1
....

带有 3 个探针的输出的第一行:

   3
0.0250 0.5000 0.1250
0.0500 0.5000 0.1250
0.1250 0.5000 0.1250
  0.0000000E+00 -1.1340826E-03  6.9640250E-02  1.6186548E-05 -4.0954774E-02 -1.5523269E-02
  0.0000000E+00 -1.5596009E-03 -3.4286277E-02  9.0128932E-05 -4.0959023E-02  6.9194414E-03
  0.0000000E+00 -3.9384158E-05 -2.2799330E-05  1.1221853E-05 -4.0955983E-02 -1.2640788E-06
  4.0196506E-02 -1.6982891E-03  6.9905423E-02  2.3351709E-05 -3.9776587E-02 -1.6820817E-02
  4.0196506E-02 -1.0372577E-03 -3.4509494E-02  6.3698954E-05 -3.9868597E-02  7.5963487E-03
  4.0196506E-02 -6.5377012E-05  3.3921110E-05  3.1376311E-05 -4.0054469E-02  1.0799556E-05
  8.0393012E-02 -1.6714063E-03  7.0387993E-02  1.5038874E-05 -4.0916789E-02 -1.8516903E-02
  8.0393012E-02 -1.1169951E-03 -3.4756862E-02  4.9885574E-05 -4.0875671E-02  8.4853258E-03
  8.0393012E-02 -9.1204643E-05  2.6588890E-05  2.1999171E-05 -4.0515620E-02  1.9732526E-05
  1.2058952E-01 -1.6174557E-03  7.0969499E-02  1.3969087E-05 -3.9974914E-02 -2.0067937E-02
  1.2058952E-01 -1.1945215E-03 -3.4945342E-02  4.9125530E-05 -3.9976085E-02  9.3101819E-03
  1.2058952E-01 -8.3691302E-05  1.0623141E-05  6.2817857E-06 -3.9872920E-02  3.0225340E-05
  1.6078602E-01 -1.5857685E-03  7.1464134E-02  1.4791469E-05 -4.0061323E-02 -2.1601683E-02
  1.6078602E-01 -1.2624167E-03 -3.5139814E-02  5.0977166E-05 -4.0052185E-02  1.0136956E-02
  1.6078602E-01 -6.9232853E-05 -1.8374514E-06 -8.4810929E-06 -3.9979475E-02  4.0127930E-05

【问题讨论】:

  • 到目前为止你尝试过什么?你发现了什么问题?
  • 这是真正的缩进吗?或者您的示例中的行首是否应该没有空格?
  • @DiegoTorresMilano 我正在编写一个 Fortran 脚本(因为它是我使用最多的语言),但是打开单元的数量有问题(打印开始进入打开单元(取决于N 的值)而不是标准输出,我开始使用越来越多的系统调用,所以决定使用 bash。经过一些研究,我发现大多数命令(split,csplit)都以更加序列化的方式工作。
  • @BenjaminW。是真正的缩进。输出由 Fortran 代码生成,格式共有 15 个字符 (1p20E15.7)。第 14 个字符是空格或减号,第 15 个字符是分隔列的空格。

标签: bash text split


【解决方案1】:

你可以这样做:

read n < infile
for ((i = 0; i < n; ++i)); do
    sed -n "$((n+2+i))~${n}p" infile > "outfile$i.txt"
done

这会将输入文件的第一行读入n,修剪空白,因此对于示例,它将包含3

然后循环遍历01、...、n-1,例如:012,将i 设置为该值。 sed 命令扩展为:

sed -n '5~3p' infile > outfile0.txt
sed -n '6~3p' infile > outfile1.txt
sed -n '7~3p' infile > outfile2.txt

其中第一行地址是n+2+i 的结果,3$n 的值。不匹配的行的输出被-n 抑制。输出文件使用i 的值进行编号。

请注意,此地址的 sed 构造 n~m(从 n 行开始,然后点击每个 mth 行)需要 GNU sed。

【讨论】:

    【解决方案2】:

    你可以试试这个

    awk 'NR==1 {n=$1} NR<=(n+1) {next} {print > sprintf("probe%d",NR%n+1)}' infile
    

    这会读取infile 并生成带有相应行的probeN 文件。 这只是 1 个进程,如果你有大文件,它会有所作为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-04
      • 1970-01-01
      • 1970-01-01
      • 2014-10-04
      • 2013-02-04
      • 2015-08-08
      • 1970-01-01
      • 2010-11-03
      相关资源
      最近更新 更多