7

I would like to be able to split an authorization code by the - character so that I can operate on each segment individually. I do not want to use external binaries (awk, grep) - this is to be as minimalistic as possible. What are some ways I can achieve this?

Here is an example auth code:

82a8-bd7d-986d-9dc9-41f5-fc02-2c20-3175-097a-c1eb

Jay Hellwig
  • 73
  • 1
  • 5

5 Answers5

15

Try using the Internal Field Separator (IFS):

AUTH_CODE='82a8-bd7d-986d-9dc9-41f5-fc02-2c20-3175-097a-c1eb'

OIFS=$IFS                   # store old IFS in buffer
IFS='-'                     # set IFS to '-'

for i in ${AUTH_CODE[@]}    # traverse through elements
do
  echo $i
done

IFS=$OIFS                   # reset IFS to default (whitespace)

Output:

82a8
bd7d
986d
9dc9
41f5
fc02
2c20
3175
097a
c1eb

By setting the Internal Field Separator, you split AUTH_CODE on the - character, allowing you to traverse through the newly-created elements in a foreach loop.

Daniel Li
  • 837
  • 2
  • 10
  • 23
  • If you haven't altered IFS from its default, you can ignore the saving the value of IFS into OIFS parts and just `unset IFS` when you're done. – violet Sep 12 '12 at 02:26
  • Could you explain the syntax `${AUTH_CODE[@]}`? Is the `[@]` what causes bash to split the string? – Sam Goldberg Dec 16 '14 at 21:35
  • I tested this on Linux, it seems like was only required to set the IFS, and after that, the string is already split. ie: ` OIFS=$IFS;IFS='-';for s in $AUTH;do echo $s;done;IFS=$OIFS` The `[@]` did not seem to be needed at all? – Sam Goldberg Dec 16 '14 at 21:45
5

You can use IFS but this is simpler:

echo "82a8-bd7d-986d-9dc9-41f5-fc02-2c20-3175-097a-c1eb"- \
  | while read -d - i; do echo "$i"; done

Please take notice of added - after string to split — read will ignore the last token otherwise.

Tometzky
  • 2,649
  • 4
  • 26
  • 32
  • 1
    this doesn't add the readability I want though, considering the operations on each element is rather intensive – Jay Hellwig Aug 22 '12 at 17:50
  • 2
    I don't understand. What's not readable? You don't need to do this in one line — you can have as many lines as you want between `do` and `done`. – Tometzky Aug 22 '12 at 17:54
4

Another way with pattern matching and array:

AUTH_CODE='82a8-bd7d-986d-9dc9-41f5-fc02-2c20-3175-097a-c1eb'
array=( ${AUTH_CODE//-/ } )
for j in ${array[@]} ; do echo $j ; done
adaptr
  • 16,479
  • 21
  • 33
ott--
  • 1,081
  • 1
  • 11
  • 13
2

Just use parameters expansion:

AUTH_CODE='82a8-bd7d-986d-9dc9-41f5-fc02-2c20-3175-097a-c1eb'
echo "${AUTH_CODE//-/$'\n'}"

Output:

82a8
bd7d
986d
9dc9
41f5
fc02
2c20
3175
097a
c1eb
Thor
  • 465
  • 5
  • 14
0
for i in {1..10}; do echo '82a8-bd7d-986d-9dc9-41f5-fc02-2c20-3175-097a-c1eb'|cut -d"-" -f$i;done
Tom
  • 146
  • 1