Извлечь подстроку из переменной (можно использовать сопоставление с шаблоном), используя bash unix? - PullRequest
0 голосов
/ 22 апреля 2020

У меня есть значение в переменной как:

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 "")

Не могли бы вы исправить вышеприведенную команду или предложить что-то еще?

Ответы [ 3 ]

1 голос
/ 22 апреля 2020

Предполагая, что вы установили 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")

Это дает преимущество в том, что разделителями на самом деле являются не ключевые слова, которые вы отправили, а символы обратной кавычки , --output-delimiter необходимо, поскольку в противном случае поля также будут разделены обратной кавычкой в ​​выходных данных.

0 голосов
/ 22 апреля 2020

Если вы хотите чистое bash решение, попробуйте:

#!/bin/bash

partition_column='| PARTITIONED BY ( | | `part_col1` int, | | `part_col2` int) | | ROW FORMAT SERDE |'

left="${partition_column#*\`}"                  # remove everything until first `
target1="${left%%\`*}"                          # remove everything from first `
right="${partition_column%\`*}"                 # remove everything from last `
target2="${right##*\`}"                         # remove everything until last `

echo "$target1" "$target2"
0 голосов
/ 22 апреля 2020
partition_column='| PARTITIONED BY ( | | `part_col1` int, | | `part_col2` int) | | ROW FORMAT SERDE |'
# extract everything between the patterns
<<<"$partition_column" sed 's/.*PARTITIONED BY\(.*\)ROW FORMAT SERDE.*/\1/' |
  # replace spaces for newlines
  tr ' ' '\n' |
  # filter only lines starting with \`
  grep '^`' |
  # remove the \`
  sed 's/`//g' |
  # join lines using a space
  paste -sd ' '

Но это возможно только с sed, просто используйте глобальную маску, чтобы сначала извлечь символы внутри `, а затем заменить их:

sed 's/.*PARTITIONED BY\(.*\)ROW FORMAT SERDE.*/\1/; s/[^`]*`\([^`]*\)`[^`]*/\1`/g; s/`/ /g; s/ $//;'

Или с помощью sed вы можете l oop с 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 //;'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...