0

I have a value in a variable as :

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

I want to extract values between PARTITIONED BY and ROW FORMAT SERDE , in above case its part_col1 and part_col2

Desired output:
part_col1 part_col2

I have tried many commands nothing seems to be working :

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

could you please correct above command , or suggest something else?

1
  • Please tag your question using the bash tag, if you are interested in only a bash solution. Further, your assignment statement partition_column=.... is incorrect (did you ever try to copy and paste it to the command line), since it would interpret part_col1 as the name of a command, and tries to run it. Commented Apr 22, 2020 at 7:10

3 Answers 3

1

Assuming that you have installed GNU cut, the following would work in bash:

 partition_column='| PARTITIONED BY ( | | `part_col1` int, | | `part_col2` int) | | ROW FORMAT SERDE |'
 result=$(cut -d '`' -f 2,4 --output-delimiter=' ' <<<"$partition_column")

This takes the advantage, that the delimiters are really not the keywords you posted, but backquote characters. The --output-delimiter is necessary, because otherwise the fields would also be separated by a backquote in the output.

Sign up to request clarification or add additional context in comments.

Comments

0
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 ' '

But it's possible with only sed, just use a global mask to first extract the chars within `, then replace them:

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

Or with sed you can loop with t until all the replacements are removed/shifted:

<<<"$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 //;'

Comments

0

If you want a pure bash solution, try:

#!/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"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.