用于解析可能引用字段的字符串的通用shell / bash方法?

时间:2012-04-13 01:25:40

标签: string bash parsing textfield

在编写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

我通常会使用ERE=~ bash运算符([[ $string =~ $pattern ]]),但每次都是真正的痛苦。

我非常确定任何变量修改,cutawksed可以非常有用,并自动处理引号和其他内容,但我可以&#39找不到特殊的神奇食谱。

2 个答案:

答案 0 :(得分: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"

答案 1 :(得分: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变量还可用于指定字段分隔符。

如果您要求未加引号的撇号可能出现在未加引号字段中,则需要稍作更改 - 请告知我。