从shell脚本中将文件的一部分提取到变量

时间:2016-03-22 19:11:00

标签: regex bash perl command-line sed

我正在编写一个旨在在OS X中以bash运行的脚本。我的Markdown文件看起来像这样:

# File name

## Heading 1

Some text


## Heading 2

* List item 1
* List item 2


## Some other section
...

我正在尝试将Heading 2内的所有内容读入变量,我尝试使用sedgrepperl,但无法获取一个有效的解决方在这些工具中,它(在理论上)看起来是可能的,并且最容易使用Perl,特别是考虑到我需要多行。它看起来像这个正则表达式(至少使用javascript语法):

## Heading 2\s+(.+)\s+

我想保持一个单行,并坚持只有现货OS X(El Capitan,10.11)提供的工具。假设我只预先知道“标题2”,而不是下面的标题标题。

3 个答案:

答案 0 :(得分:1)

使用sed

head2="$(sed -n '/## Heading 2/,/## Heading 3/{s/^## Heading .*//;p;}' file)"

echo "$head2"


* List item 1
* List item 2

使用perl

head2="$(perl -0pe 's/(?s).*## Heading 2\s*(.*)\s*## Heading 3.*/\1/' file)"

echo "$head2"
* List item 1
* List item 2

您还可以使用grep安装 gnu home brew并使用此正则表达式:

head2="$(grep -zoP '## Heading 2\s*\K[\s\S]*(?=\s*## Heading 3)' file)"

答案 1 :(得分:1)

使用sed:

$ myvar=$(sed "/^## $1$/,/^## Heading/!d;//d;/^$/d" file)
$ echo "$myvar"
* List item 1
* List item 2

如果您想保留空行,可以删除/^$/d

更新:

我已用双引号替换单引号以允许shell扩展。

您可以使用./scriptname.sh "Heading 2"调用它。

一些解释:

  • /^## $1$/,/^## Heading/将后续命令应用于与第一个模式匹配的行,直到包含第二个模式的下一行。
  • !d删除除该范围对应的所有行。
  • //d匹配与地址相同的模式并将其删除。

答案 2 :(得分:0)

您可以使用items范围:

awk

或变量

awk '/^## Heading 2/,/^## Heading [^2]/ {if (!/^## Heading 2/&&!/^## Heading [^2]/) { print}}'