【问题标题】:Extract section of file to a variable, from within a shell script从 shell 脚本中将文件的一部分提取到变量中
【发布时间】:2016-07-09 20:35:14
【问题描述】:

我正在编写一个旨在在 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”,而不知道下面的标题标题。

【问题讨论】:

    标签: regex bash perl command-line sed


    【解决方案1】:

    您可以使用awk 范围:

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

    或带变量

    awk '/s/,/e/ {if ($0 !~ s && $0 !~ e) { print}}' s='^## Heading 2' e='^## Heading [^2]'
    

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

        【解决方案3】:

        使用 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”作为 bash 脚本的参数读取?我尝试用$1 替换它,但没有输出。
        • @Dov 变量在双引号字符串内展开,而不是单引号字符串。
        • 我需要做一些调整 - 你能详细说明你的 sed 表达式的每个部分在做什么吗?
        猜你喜欢
        • 1970-01-01
        • 2015-10-20
        • 1970-01-01
        • 2014-03-29
        • 1970-01-01
        • 1970-01-01
        • 2021-10-23
        • 1970-01-01
        相关资源
        最近更新 更多