简体   繁体   中英

Extracting part of a string to a variable in bash

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.

Pure Bash using an array:

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

The output:

value = 67890

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM