2

在编写 munin 脚本时,我经常需要解析配置文件以寻找一些路径。

没有强标记(即不是 XML)的配置文件的问题是这些路径可以有多种语法:

  • 单引号 (') 或双引号 (") 或不带引号
  • 包含空格(如果字符串未加引号,则转义)
  • 包含引号(通常是单引号)

例如,我正在寻找一种方法来解析以下行以提取路径(这一次,在第一个位置):

/mnt/DirWithoutSpaces/ "Dir1" cnidscheme:dbd perm:0775 options:usedots,upriv
/mnt/Dir\ With\ Space/ Dir2 cnidscheme:dbd options:usedots,upriv
"/mnt/Dir With Space And D-quote" Dir3
'/mnt/Dir With Space And S-quote' Dir4
~/ "Dir 5" cnidscheme:dbd
"/mnt/Dir'ed" "Dir 6" cnidscheme:dbd

我通常会使用bash 运算符 ( ) ERE,但每次都让我头疼。=~[[ $string =~ $pattern ]]

我很确定任何变量修饰,,,cutawk可以sed非常有用并自动处理引号和其他东西,但我找不到那个特殊的神奇配方。

4

2 回答 2

3

您可以尝试以下-P (--perl-regexp)选项grep

$ grep -oP "^(\\\\ |[^ '\"])*" input.txt
/mnt/DirWithoutSpaces/
/mnt/Dir\ With\ Space/
~/

$ grep -oP "^(['\"]).*?\1" input.txt
"/mnt/Dir With Space And D-quote"
'/mnt/Dir With Space And S-quote'
"/mnt/Dir'ed"

$ grep -oP "^(['\"]).*?\1|^(\\\\ |[^ '\"])*" input.txt
/mnt/DirWithoutSpaces/
/mnt/Dir\ With\ Space/
"/mnt/Dir With Space And D-quote"
'/mnt/Dir With Space And S-quote'
~/
"/mnt/Dir'ed"
于 2012-04-13T02:23:19.510 回答
0

我写了几个本机 bash 函数来做到这一点:https ://github.com/mblais/bash_ParseFields

您可以ParseFields像这样使用该功能:

$ str='field1 field\ 2 "field 3"'
$ ParseFields -d "$str" a b c d
$ printf "|%s|\n|%s|\n|%s|\n|%s|\n" "$a" "$b" "$c" "$d"
|field1|         
|field 2|
|field 3|
||                

ParseFields的-d选项会删除任何周围的引号并解释解析字段中的反斜杠。

还有一个更简单的ParseField函数(由 使用ParseFields)解析字符串中特定偏移量的单个字段。

请注意,这些函数无法解析,只能解析字符串。IFS 变量还可用于指定除空格之外的字段分隔符。

如果您要求未转义的撇号可能出现在未引用的字段中,则需要稍作更改 - 让我知道。

于 2014-02-26T22:48:34.867 回答