【问题标题】:How to get portion of ini file by section using sed in bash如何在bash中使用sed按部分获取ini文件的一部分
【发布时间】:2020-06-09 05:20:11
【问题描述】:

如何使用 sed 按节名获取 ini 文件的一部分。 棘手的部分是节名可能有文件路径。

我的 ini 示例:

[SECTION]
ANYkey=value1
ANYkey2=value2

[test/foo/file.txt]
key=value1
key2=value2

[test/foo/file2.txt]
key3=value3
key4=value4

问题在于检索 ini 部分 [test/foo/file.txt] 的数据

sed 或 awk 后的预期输出:

key=value1
key2=value2

我已经在下面编码以获得 [SECTION] 部分使用下面

sed -e 's/[[:space:]]*\=[[:space:]]*/=/g' -e 's/#.*$//' -e 's/[[:space:]]*$//' -e 's/^[[:space:]]*//' -e "s/^\(.*\)=\([^\"']*\)$/\1=\"\2\"/" < file.ini | sed -n -e "/^\[SECTION\]/,/^\s*\[/{/^[^#].*\=.*/p;}"

使用 sed 获取输出,如

ANYkey=value1
ANYkey2=value2

但由于文件路径([test/foo/file.txt] 之间的斜线),此逻辑不适用于其他部分

【问题讨论】:

  • 能否请您在您的问题中更清楚一些,因为它不清楚获取输出的逻辑是什么(您想删除路径行吗?)。另外,请添加您为解决您自己的问题所做的努力,然后让我们知道。
  • @RavinderSingh13:当然。这是提供更多说明的示例。我的 file.ini 如下所示 ``` [SECTION] anykey=anyvalue anykey2=anyvalue2 [test/foo/file.txt] key=value1 key2=value2 ```
  • 我可以使用下面的 sed 获取部分 SECTION 但无法检索其他部分 ([test/foo/file.txt]) ``` sed -e 's/[[:space: ]]*\=[[:space:]]*/=/g' -e 's/#.*$//' -e 's/[[:space:]]*$//' -e ' s/^[[:space:]]*//' -e "s/^(.*)=([^\"']*)$/\1=\"\2\"/"
  • 好的,感谢您的努力,请将它们添加到您的问题中(因为 cmets 并不意味着显示代码)和代码标签,然后让我们知道。
  • 请重新检查我的帖子

标签: regex awk sed


【解决方案1】:

EDIT2: 或者根据 OP 的评论,如果您想获取值作为传递给脚本的参数,请尝试以下操作。当 OP 需要将路径详细信息作为参数传递给 shell 脚本并将其传递给 awk 程序以获得所需的输出时,应该使用它。

cat script.ksh
value="$1"
awk -v var="$value" '/^\[/{found=""} $0 ~ var{found=1;next}  found && NF' Input_file

如下运行脚本,输出为:

./script.ksh "test/foo/file.txt"
key=value1
key2=value2


编辑:根据 OP 的评论来寻找特定的 pat try following。当 OP 想要在awk 程序本身中直接传递路径详细信息时应该使用。

awk '/^\[/{found=""} /^\[test\/foo\/file\.txt\]$/{found=1;next} found && NF' Input_file

awk '/^\[/{found=""} $0 == "[test/foo/file2.txt]"{found=1;next} found && NF' Input_file

上面的解释:

awk '                              ##Starting awk program from here.
/^\[/{                             ##Checking if a line starts from [.
  found=""                         ##Nullifying found here.
}
/^\[test\/foo\/file\.txt\]$/{       ##Checking if a line contains [test/foo.... then do following.
  found=1                          ##Setting found here.
  next                             ##next will skip all further statements from here.
}
found && NF                        ##Checking if found is SET and line is NOT empty then print current line.
' Input_file                       ##Mentioning Input_file name here.


根据您显示的示例,您能否尝试以下操作。在需要打印[ 之后的任何部分时使用。

awk '/^\[/{found=""} /^\[.*\//{found=1;next} found' Input_file

上面的解释:

awk '           ##Starting awk program from here.
/^\[/{          ##Checking if a line starts with [ then do following.
  found=""      ##Nullifying found here.
}
/^\[.*\//{      ##Checking condition if line starts from [ and have / in it for path then do following.
  found=1       ##Setting found to 1 here.
  next          ##next will skip all further statements from here.
}
found           ##If found is set then print current line.
' Input_file    ##Mentioning Input_file name here.

【讨论】:

  • 好的,我试试
  • 如果我的 ini 有多个文件路径部分,这将无法解决。 [test/foo/file.txt] key=value [test/foo/file2.txt key=value2 [test/foo/file3.txt] key=value3
  • 当然。让我试试……非常感谢 Champ!
  • 使用/^\[test\/foo\/file.txt\]$/,您试图转义所有正则表达式元字符(您错过了. -> \.)和分隔符,以使正则表达式比较表现得像字符串比较。不要那样做 - 只需进行字符串比较 $0 == "[test/foo/file2.txt]",因为这样更简单、更健壮且不易出错。
  • @EdMorton,谢谢先生的告知,在 OR 解决方案中补充了这一点 + 在代码中修复了转义 .,干杯。
【解决方案2】:
$ awk -v sec='[test/foo/file2.txt]' '!NF{f=0} f; $0==sec{f=1}' file
key3=value3
key4=value4

【讨论】:

    猜你喜欢
    • 2011-04-13
    • 1970-01-01
    • 2015-02-05
    • 2019-10-04
    • 2014-04-28
    • 1970-01-01
    • 1970-01-01
    • 2013-05-16
    • 1970-01-01
    相关资源
    最近更新 更多