使用bash unix从变量(使用模式匹配)中提取子字符串?

使用bash unix从变量(使用模式匹配)中提取子字符串?,bash,Bash,我在变量中有一个值,如下所示: partition_column='| PARTITIONED BY ( | | `part_col1` int, | | `part_col2` int) | | ROW FORMAT SERDE |' 我想提取PARTITIONED BY和ROW FORMAT SERDE之间的值,在上面的例子中是它的part_col1和part_col2 Desired output: part_col1 part_col2 我尝试了许多命令,但似乎没有任何效果: res

我在变量中有一个值,如下所示:

partition_column='| PARTITIONED BY ( | | `part_col1` int, | | `part_col2` int) | | ROW FORMAT SERDE |'
我想提取PARTITIONED BY和ROW FORMAT SERDE之间的值,在上面的例子中是它的part_col1和part_col2

Desired output:
part_col1 part_col2
我尝试了许多命令,但似乎没有任何效果:

result=$(echo $par_col | sed -nr '/`/p'|  cut -d '`' -f 2|xargs -n 1 echo -n "")

请您更正上述命令,或提出其他建议好吗?

假设您已安装GNU
cut
,则以下命令在bash中可用:

 partition_column='| PARTITIONED BY ( | | `part_col1` int, | | `part_col2` int) | | ROW FORMAT SERDE |'
 result=$(cut -d '`' -f 2,4 --output-delimiter=' ' <<<"$partition_column")
partition_column='|被(| | `part_col1`int,| | `part_col2`int)| |行格式SERDE |分割
结果=$(剪切-d'''-f 2,4--输出分隔符=''
或者使用sed,您可以使用
t
循环,直到移除/移动所有替换:

<<<"$partition_column" sed 's/.*PARTITIONED BY\(.*\)ROW FORMAT SERDE.*/\1/;
   # add a newline on the end
  s/$/\n/;
  :a;
     # find something within ` and move it behind the newline
     # remove everything in fron ` and after ` that is not a `
     s/[^`]*`\([^`]*\)`[^`]*\([^\n]*\n.*\)/\2 \1/;
  # loop until the `s` command above does something
  ta;
  # remove everything in front the newline and the space
  s/.*\n //;'

如果您想要纯bash解决方案,请尝试:

!/bin/bash
partition_column='|被(| | `部分| col1`int,| | `部分| col2`int)| |行格式SERDE |分割
left=“${partition\u column\\*\`}”删除所有内容,直到第一个`
target1=“${left%%\`*}”从第一个列表中删除所有内容`
right=“${partition\u column%\`*}”删除最后一个分区中的所有内容`
target2=“${right###*\`}”删除所有内容,直到最后一次`
回显“$target1”“$target2”

如果您只对bash解决方案感兴趣,请使用bash标签标记您的问题。此外,您的赋值语句
partition\u column=..
不正确(您是否尝试将其复制并粘贴到命令行),因为它会将
part\u col1
解释为命令名,并尝试运行它。
sed 's/.*PARTITIONED BY\(.*\)ROW FORMAT SERDE.*/\1/; s/[^`]*`\([^`]*\)`[^`]*/\1`/g; s/`/ /g; s/ $//;'
<<<"$partition_column" sed 's/.*PARTITIONED BY\(.*\)ROW FORMAT SERDE.*/\1/;
   # add a newline on the end
  s/$/\n/;
  :a;
     # find something within ` and move it behind the newline
     # remove everything in fron ` and after ` that is not a `
     s/[^`]*`\([^`]*\)`[^`]*\([^\n]*\n.*\)/\2 \1/;
  # loop until the `s` command above does something
  ta;
  # remove everything in front the newline and the space
  s/.*\n //;'