【问题标题】:sed regex pattern for some tricky line (ini section)一些棘手的行的 sed 正则表达式模式(ini 部分)
【发布时间】:2012-08-25 19:27:47
【问题描述】:

我想解析 *.ini 文件中的部分条目之类的内容:

line='      [          fdfd fdf         f   ]  '

这条线分割的 sed 模式 (???) 可能是什么

'fdfd fdf         f'

出去?

所以:

echo "${line}" | sed -E 's/???/\1/g'

我如何描述除 [[:space:]][] 之外的所有字符?这对我不起作用:[^[[:space:]]\[]*

【问题讨论】:

  • 尝试:echo "${line}" | sed -E 's/^[[:space:]]*\[[[:space:]]*(.*)[[:space:]]*\][[:space:]]*$/\ 1/'
  • ..或者你想匹配除中间部分之外的所有内容吗?回声“${line}”| sed -E 's/^([[:space:]]*\[[[:space:]]*).*([[:space:]]*][[:space:]]*)$/ \1\2/'

标签: regex sed pattern-matching sh


【解决方案1】:
$ echo "$line" | sed "s/^.*\[[[:space:]]*\([^]]*[^][:space:]]\)[[:space:]]*\].*$/'\1'/"

您可以将模式一分为二:

$ echo "$line" | sed "s/^.*\[[[:space:]]*/'/; s/[[:space:]]*\].*$/'/"

awk 也可以:

$ echo "$line" | awk -F' *[[\]] *' -vQ="'" '{print Q$2Q}'

【讨论】:

  • 抱歉,我忘了说:“嗨,我是 Mac”... BSD sed 没有 -r 标志。但是:回声“${line}”| sed -e 's/^.*[[[:space:]]*([^]]*[^][:space:]])[[:space:]]*].*$/\1/ ' 对我有用!或使用 -E 选项 echo "${line}" | sed -E 's/^.*[[[:space:]]*([^]]*[^][:space:]])[[:space:]]*].*$/[\1 ]/'。
  • 第二个方案很容易理解。
  • 如果 -e 选项(不是 -E),我忘记转义 '(', ')' 所以: echo "${line}" | sed -e 's/^.*[[[:space:]]*([^]]*[^][:space:]])[[:space:]]*].*$/\1/ '。谢谢
【解决方案2】:

当您使用[[:space:]] 语法时,外括号是普通的“匹配此列表中的一个字符”括号,与[aeiou] 相同,但内括号是[:space:] 的一部分,这是一个不可分割的单元。

因此,如果您想匹配属于space 类或x 的单个字符,您可以使用[[:space:]x][x[:space:]]

当您要匹配的字符之一是] 时,它将终止括号中的字符列表,除非您对其进行特殊处理。您已经猜到在某处需要反斜杠;一个很好的猜测,但错误。在列表中包含] 的方法是将其放在首位。 [ab]c] 是包含 2 个字符 ab 的括号列表,后跟 2 个文字匹配字符 c],因此它匹配 "ac]""bc]"[]abc] 是 4 个字符 @987654336 的括号列表@ 所以它匹配 "a""b""c""]"

在否定列表中,] 紧跟在 ^ 之后。

因此,将所有这些放在一起,匹配除[:space:] 类和括号之外的所有字符集中的单个字符的方法是:

[^][:space:][]

第一个括号和最后一个括号是一对匹配的,即使您认为它们看起来不应该是这样。

【讨论】:

    【解决方案3】:

    当您说拆分时,您的意思是拆分成一个数组,还是您的意思是过滤所有空格和括号?

    假设file.ini中第1行的值为:

      [          fdfd fdf         f   ]  
    

    如果你的意思是数组,

    $linenumber=1;
    array=($(sed -n ${linenumber}p file.ini | sed 's/[][]*//g'));
    

    将file.ini的第1行拆分为一个数组并返回值:

    ${array[0]} = fdfd
    ${array[1]} = fdf
    ${array[2]} = f
    

    如果你的意思是过滤空格和括号,

    $linenumber=1;
    sed -n ${linenumber}p file.ini | sed 's/[ []]*//g';
    

    将返回:

    fdfdfdff
    

    如果这两个都不是您的意思,请指定确切的输出您希望从初始值中提取,以便我们能够正确解决它。

    【讨论】:

    • 我的意思是得到:'fdfd fdf f'(不带引号,保留字符串中的所有空格:这里是修剪过的 - 我不知道用于在 cmets 中保留空格的 stackoverflow 语法,修剪所有外部空格)。但无论如何,谢谢你的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    • 2013-11-16
    相关资源
    最近更新 更多