BASH中的模式替换空间是否特殊?

时间:2017-04-06 07:40:34

标签: bash pattern-matching whitespace trim

尝试使用BASH从变量的值中删除前导和尾随空白(SPC),我觉得它不能像所描述的那样工作。 我从${var%% }${var## }开始,它应该删除最长的模式,但似乎只删除了一个空白:

% val="  a  ";echo "|${val}|${val## }|"
|  a  | a  |
% val="  a  ";echo "|${val}|${val%% }|"
|  a  |  a |

然后我尝试了模式匹配,似乎没有删除任何东西(他们也应该重复删除值的开头或结尾处的空白):

% val="  a  ";echo "|${val}|${val//# }|"
|  a  |  a  |
% val="  a  ";echo "|${val}|${val//% }|"
|  a  |  a  |

我觉得我犯了一些简单的错误,但似乎我坐在我的眼前:为什么这不起作用?

(我确实已经访问了这些答案,但他们没有包含"我的解决方案": How to trim whitespace from a Bash variable?How to remove space from string?

3 个答案:

答案 0 :(得分:2)

空间(0x20)对于glob模式和RE模式都不是特殊的。

对于您的问题,我会利用extglob shell选项:

[STEP 108] # shopt -s extglob
[STEP 109] # v='    foo    '
[STEP 110] # echo "|${v##+( )}|"
|foo    |
[STEP 111] # echo "|${v%%+( )}|"
|    foo|
[STEP 112] # echo "|${v%%+([[:blank:]])}|"
|    foo|
[STEP 113] # echo "|${v##+([[:blank:]])}|"
|foo    |
[STEP 114] #

答案 1 :(得分:0)

问题不在于特别处理空间(SPC);相反,问题是bash手册页中使用的模式是指路径名模式,而不是正则表达式(除非{{1设置(似乎默认设置))。那是extglob不是空白序列,而是空白后跟任何

第二个问题是“最长匹配模式”不会通过重复应用匹配来确定,直到失败,但只有一次。因此,如果模式不包含' *'*%会产生相同的结果,就像%%#一样。

##中的问题是:

  • ${val//# }//无法合并;只能使用一种变体。

  • /#中的
  • 模式不是正则表达式,而是路径名模式(仍然)。

这意味着使用${parameter/pattern/string}过度使用没有任何好处 ${val/# }。要删除所有前导和尾随空白,可以使用以下(有些复杂)代码:

${val# }

因此,当使用val=" a " echo -n "|${val}" while [ "_$val" != "_${val# }" ] do val="${val# }" done while [ "_$val" != "_${val% }" ] do val="${val% }" done echo "|${val}|" 时,解决方案看起来像这样(如前面的答案中所指出的):

extglob

答案 2 :(得分:-1)

您可以使用sed将其归档。

删除字符串末尾的所有前导空格和空格......

sed 's/^[ \t]*//;s/[ \t]*$//'