使用 cut 返回字符串的中间部分

使用 cut 返回字符串的中间部分

我有一个 xml 字符串回显stdout

<xml:attribute>{41c33a-4893b-3627a-617a}</xml:attribute>

{41c33a-4893b-3627a-617a}在这种情况下我想返回字符串。我正在考虑使用 cut (甚至可能用管道传输两次),但我不知道正确的语法。我正在使用 bash。

答案1

您可以使用cut-d选项来定义分隔符(从结果字段中排除):

echo "<xml:attribute>{41c33a-4893b-3627a-617a}</xml:attribute>" | cut -d\> -f2 | cut -d\< -f1

这会分割>并输出第二个字段,留下{41c33a-4893b-3627a-617a}</xml:attribute,然后再次分割<并输出第一个字段。

字段描述分隔符之间、文本开头和第一个分隔符之间以及最后一个分隔符和文本结尾之间的文本。使用>原始文本,您最终会得到:

  1. <xml:attribute
  2. {41c33a-4893b-3627a-617a}</xml:attribute
  3. 空字符串

(省略分隔符)。然后<在字段 2 上使用给出

  1. {41c33a-4893b-3627a-617a}
  2. /xml:attribute

字段 1 是您要查找的结果。

答案2

对于简单的字符串操作,您通常应该使用 shell 自己的构造,绑定到参数扩展。外部实用程序更适合处理大量文本,但对于单个字符串,启动外部工具很慢并且正确引用可能很困难。

mystring='<xml:attribute>{41c33a-4893b-3627a-617a}</xml:attribute>'
content="${mystring#*>}"; content="${content%<*}"
braced="${mystring#*\{}"; braced="${braced%%\}*}"; braced="{$braced}"

content设置为原始字符串减去前导和尾随<…>部分。braced设置为看起来像 的第一部分{…}

答案3

您还可以sed提取由正则表达式指定的字段。如果您有更复杂的匹配条件,则很有用:

echo '<xml:attribute>{41c33a-4893b-3627a-617a}</xml:attribute>' | \
sed -E 's/^.+>({.+})<.+$/\1/'

答案4

或者使用awk,使用正则表达式<|>作为字段分隔符:

$ echo "<xml:attribute>{41c33a-4893b-3627a-617a}</xml:attribute>" | 
       awk -F '<|>' '{print $3}'
{41c33a-4893b-3627a-617a}

注意:使用 GNU awkmawk和进行测试original-awk。在这三个中的工作原理相同。

perl版本非常相似(除了perl数组是从零开始的,并且perlprint语句不会输出尾随,\n除非您明确告诉它):

echo "<xml:attribute>{41c33a-4893b-3627a-617a}</xml:attribute>" |
     perl -n -a -F'<|>' -e 'print $F[2],"\n"'

另请注意 - 这只能可靠地工作,因为它是包含单个 XML 片段的单行输入。正则表达式不能用于可靠地解析实际的 XML。请使用 XML 解析工具来代替,例如,或用于、、 和其他语言xmlstarlet的许多 XML 解析库之一。perlpython

相关内容