行为不端?

时间:2011-10-25 20:50:51

标签: regex bash sed

我有以下命令:

$ xlscat -i $file

我得到了:

Excel File Name.xslx - 01:  [ Sheet #1      ] 34 Cols,    433 Rows
Excel File Name.xlsx - 02:  [ Sheet Number2 ] 23 Cols,     32 Rows
Excel File Name.xlsx - 03:  [ Foo Factor!   ] 14 Cols,    123 Rows

我只想要工作表名称,所以我这样做:

$ xlscat -i $file 2>&1 | sed -e 's/.*\[  *\(.*\)  *\].*/\1/' | while read file
> do
>    echo "File: '$file'"
> done

得到这个:

File: 'Sheet #1'
File: 'Sheet Number2'
File: 'Foo Factor!'

大!一切都很美妙。正如您在单引号中看到的那样,我删除了文件名末尾的额外空格。现在将所有剩余空格转换为下划线:

$ xlscat -i $file 2>&1 | sed -e 's/.*\[  *\(.*\)  *\].*/\1/' | sed -e 's/ /_/g' |  while read file
> do
>    echo "File: '$file'"
> done

现在我明白了:

File: 'Sheet_#1_____'
File: 'Sheet_Number2'
File: 'Foo_Factor!__'

咦?第一个没有显示任何尾随空白,但第二个似乎是在文件末尾附加下划线。我没看到什么?

3 个答案:

答案 0 :(得分:4)

我认为read file正在修剪尾随空白。尝试把

sed -e 's/ /_/g'

在while循环中...就像:

echo "File: $(echo $file | sed -e 's/ /_/g')"

答案 1 :(得分:4)

第一个sed命令没有剥离尾随空格,read是。检查你的表达:

 sed -e 's/.*\[  *\(.*\)  *\].*/\1/'

匹配:

  1. 任何
  2. 一个支架
  3. 1个或更多空格
  4. 捕获的任何内容
  5. 1个或更多空格
  6. 右括号
  7. 任何
  8. 正则表达式是贪婪的,这意味着它们尽可能匹配,而之前的表达式将在之后的表达式之前匹配。因此,例如,正则表达式(.*)(.*)匹配两个捕获组中的任何内容,但是可以通过多种方式在两个组之间分割数据。因此正则表达式实现必须选择,它将尽可能多地放在第一个中,而在第二个中没有任何内容。

    由于您需要将文件名与空格匹配,因此您无法匹配“除空格之外的任何内容”;你最好的办法是将尾随空白作为一个单独的步骤进行修剪。请尝试使用此sed命令:

    sed -e 's/.*\[  *\(.*\)  *\].*/\1/' -e 's/ *$//'
    

答案 2 :(得分:0)

是否echo剥离了尾随空格?虽然它看起来似乎应该出现在引号内。无论如何,试试这个:

sed -e 's/.*\[ *\([^] ]\+\( \+[^] ]\+\)*\).*/\1/'

工作表名称的每个单词都与[^] ]\+匹配(即除空格或]以外的任何字符中的一个或多个)。当匹配名称的最后一个单词时,第二个.*消耗该行的其余部分。没有必要匹配结束],因此不必在匹配中包含尾随空格。

我不是sed用户,但是当我指定GNU-BRE风格时,此正则表达式在RegexBuddy中正常工作,因此它应该在sed中工作。