16

noob here, sorry if a repost. I am extracting a string from a file, and end up with a line, something like:

abcdefg:12345:67890:abcde:12345:abcde

Let's say it's in a variable named testString the length of the values between the colons is not constant, but I want to save the number, as a string is fine, to a variable, between the 2nd and 3rd colons. so in this case I'd end up with my new variable, let's call it extractedNum, being 67890 . I assume I have to use sed but have never used it and trying to get my head around it... Can anyone help? Cheers

On a side-note, I am using find to extract the entire line from a string, by searching for the 1st string of characters, in this case the abcdefg part.

fedorqui
  • 275,237
  • 103
  • 548
  • 598
Steven Cragg
  • 175
  • 1
  • 2
  • 8
  • possible duplicate of [How to trim whitespace from bash variable?](http://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-bash-variable) – user2284570 Jul 26 '14 at 14:17

4 Answers4

19

Pure Bash using an array:

testString="abcdefg:12345:67890:abcde:12345:abcde"
IFS=':'
array=( $testString )
echo "value = ${array[2]}"

The output:

value = 67890
Fritz G. Mehner
  • 16,550
  • 2
  • 34
  • 41
13

Here's another pure bash way. Works fine when your input is reasonably consistent and you don't need much flexibility in which section you pick out.

extractedNum="${testString#*:}"     # Remove through first :
extractedNum="${extractedNum#*:}"   # Remove through second :
extractedNum="${extractedNum%%:*}"  # Remove from next : to end of string

You could also filter the file while reading it, in a while loop for example:

while IFS=' ' read -r col line ; do
    # col has the column you wanted, line has the whole line
    # # #
done < <(sed -e 's/\([^:]*:\)\{2\}\([^:]*\).*/\2 &/' "yourfile")

The sed command is picking out the 2nd column and delimiting that value from the entire line with a space. If you don't need the entire line, just remove the space+& from the replacement and drop the line variable from the read. You can pick any column by changing the number in the \{2\} bit. (Put the command in double quotes if you want to use a variable there.)

William
  • 4,787
  • 2
  • 15
  • 14
  • Old post, but because yr answer was accepted, could you complete it with an ever so short explanation of the 'done < <(sed ...)' syntax ? (the sed part is clear, i am wondering about the two right to left redirect-like <. Tx. – Cbhihe Dec 06 '15 at 20:28
  • How would I extract `("123" "vbm-container")` from this? echo $raw_containers_string [ { "name": "123" }, { "name": "vbm-container" } ] – feedthemachine Aug 12 '22 at 22:29
7

You can use cut for this kind of stuff. Here you go:

VAR=$(echo abcdefg:12345:67890:abcde:12345:abcde |cut -d":" -f3); echo $VAR

For the fun of it, this is how I would (not) do this with sed, but I'm sure there's easier ways. I guess that'd be a question of my own to future readers ;)

echo abcdefg:12345:67890:abcde:12345:abcde |sed -e "s/[^:]*:[^:]*:\([^:]*\):.*/\1/"
Miquel
  • 15,405
  • 8
  • 54
  • 87
  • Thanks for the lightning response, I'll give it a go! – Steven Cragg Apr 09 '13 at 08:48
  • And on another note, how would I then use that later to put this number back into a new string, replacing what's in between the second and third colons? – Steven Cragg Apr 09 '13 at 08:57
  • I suppose `awt` is better suited the more complext it goes. With sed, you could do `echo abcdefg:12345:67890:abcde:12345:abcde | sed -e "s/\([^:]*:[^:]*:\)[^:]*\(:.*\)/\1WHATEVER\2/"` – Miquel Apr 09 '13 at 09:14
2

this should work for you: the key part is awk -F: '$0=$3'

NewVar=$(getTheLineSomehow...|awk -F: '$0=$3')

example:

kent$  newVar=$(echo "abcdefg:12345:67890:abcde:12345:abcde"|awk -F: '$0=$3')

kent$  echo $newVar 
67890

if your text was stored in var testString, you could:

kent$  echo $testString                                                                                                                                                     
abcdefg:12345:67890:abcde:12345:abcde
kent$  newVar=$(awk -F: '$0=$3' <<<"$testString")
kent$  echo $newVar                                                                                                                                                         
67890
Kent
  • 189,393
  • 32
  • 233
  • 301