Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 在以“开始”的两行之间提取行$&引用;与塞德_Bash_Sed - Fatal编程技术网

Bash 在以“开始”的两行之间提取行$&引用;与塞德

Bash 在以“开始”的两行之间提取行$&引用;与塞德,bash,sed,Bash,Sed,我有一个很大的文本文件,其中包含一些数据,如下所示: $ 10c20 data data . . data data $ 10c21 data data . . data data $ 10c22 . . 我想在每两个注释行(以“$”开头)之间提取数据,并将该数据块存储在新文件中,然后存储到下一个数据块,直到文件结束。我尝试了“sed”,但无法获得我所需要的。有什么想法吗 期望输出: $ 10c20 data data . . data

我有一个很大的文本文件,其中包含一些数据,如下所示:

$  10c20
data
data
.
.
data
data
$  10c21
data
data
.
.
data
data
$  10c22
.
.
我想在每两个注释行(以“$”开头)之间提取数据,并将该数据块存储在新文件中,然后存储到下一个数据块,直到文件结束。我尝试了“sed”,但无法获得我所需要的。有什么想法吗

期望输出:

$  10c20
    data
    data
    .
    .
    data
    data


而且…

如果您不想要像Python/Perl这样的“更高级”语言,有一个通用的内置
csplit
,不过您需要同意使用文件:

/home/.../RGS/tmp>csplit bla  '/^\$/' {*} 
0
21
21
21
21
/home/.../RGS/tmp>cat xx00
/home/.../RGS/tmp>cat xx01
$  10c20
data1
data1
/home/.../RGS/tmp>cat xx02
$  10c21
data2
data2
/home/.../RGS/tmp>cat xx03
$  10c22
data3
data3
/home/.../RGS/tmp>cat xx04
$  10c23
data4
data4
/home/.../RGS/tmp>
其中,bla是:

$  10c20
data1
data1
$  10c21
data2
data2
$  10c22
data3
data3
$  10c23
data4
data4
最后就是
rmxx*

编辑

文件准备好后,在bash中只需执行以下操作:

for inp in xx*; do
     cat $inp | toSomeComputations &
     #Or
     toSomeComputations $inp &
 done

当然,您可以使用其他方法使这个循环并行。

这里有一个GNUawk脚本,它复制了@kabanus答案。当@kabanus给出的答案对你不起作用时,我不知道这对你有什么帮助,但在这里

script.awk

function doit( header ) { 
    # filename with leading zeros in number
    outFileName = sprintf("out_%04d", NR-1)
    printf("%s%s", header, $0 ) > outFileName
    # now lets run a command on that file, e.g. cat
    system("cat " outFileName )
}

# set record split by the dollar lines
BEGIN   { RS="[$][^\n]+" }

{ 
  # on NR == 1 ( the first record ) oldRT is empty
  # we need to store RT and use oldRT when we output $0 
  # for the next record
  if( oldRT ) doit( oldRT )
  oldRT = RT
}
按如下方式运行:
awk-f script.awk您的文件

您只需要:

awk '
function doCalculation() {
    # do whatever you want with the multi-line string "buf" then
    printf "%s", buf
    buf = ""
}
/^\$/ { doCalculation() }
{ buf = buf $0 ORS }
END { doCalculation() }
' file

如果更方便的话,您可以将buf设置为数组而不是多行字符串,但两种方式的逻辑相同。

很难/不可能将sed用于多行操作。一行最多两行是我“轻松”完成的工作。任何语言都是可能的吗?请将您对该示例输入的期望输出也添加到您的问题中。@kabanus我已经做过类似的事情,只有两行不同的模式,但我不知道如何做我刚才注意到这一行是相似的,不确定它是否是重复的。您为什么这么说:“不同的是,我在评论行的开头有相同的字符"? 我第一次很好地理解了你,不管怎么说,似乎是这样。如果你愿意编辑,我会帮助你,否则我会有点麻烦。我想你不明白我想要什么,两个注释行之间的数据是可变的,而且很大,不能使用你的代码。无论如何,这都是“可变的和巨大的”数据,但也许你应该考虑使用一个更容易的语言脚本。如果您不清楚分割后如何处理文件,我将进行编辑。这是一个庞大的并行计算程序,因此没有帮助,我只想将提取的块粘贴到另一个文件中,作为所述程序的输入。哪一块是并行的?为什么要使用Linux命令执行此操作?你需要把这些东西都写在问题里,而不是死后写在答案上。请用整个流程重新写问题。循环这些文件并cat/将它们交给另一个进程很容易……我从来没有说过我想使用bash进行并行计算!我刚才说我想把提取的数据块复制粘贴到另一个文件中,这个文件是为另一个程序输入的。后者将在不知道输入是如何产生的情况下进行并行计算!我刚才回答了Lars关于计算的问题,我能把提取的每个数据块打印到单独的文件中吗?(考虑循环)请稍等,我离开键盘了。
function doit( header ) { 
    # filename with leading zeros in number
    outFileName = sprintf("out_%04d", NR-1)
    printf("%s%s", header, $0 ) > outFileName
    # now lets run a command on that file, e.g. cat
    system("cat " outFileName )
}

# set record split by the dollar lines
BEGIN   { RS="[$][^\n]+" }

{ 
  # on NR == 1 ( the first record ) oldRT is empty
  # we need to store RT and use oldRT when we output $0 
  # for the next record
  if( oldRT ) doit( oldRT )
  oldRT = RT
}
awk '
function doCalculation() {
    # do whatever you want with the multi-line string "buf" then
    printf "%s", buf
    buf = ""
}
/^\$/ { doCalculation() }
{ buf = buf $0 ORS }
END { doCalculation() }
' file