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

2
  • Normally you would use cut. Why the limitation on external binaries though?
    – Grant
    Aug 22, 2012 at 17:35
  • This is on an embedded Linux device with limited access to them. Aug 22, 2012 at 17:38

5 Answers 5

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.

3
  • 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, 2012 at 2:26
  • Could you explain the syntax ${AUTH_CODE[@]}? Is the [@] what causes bash to split the string? Dec 16, 2014 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? Dec 16, 2014 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.

2
  • 1
    this doesn't add the readability I want though, considering the operations on each element is rather intensive Aug 22, 2012 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, 2012 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
0
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
0
for i in {1..10}; do echo '82a8-bd7d-986d-9dc9-41f5-fc02-2c20-3175-097a-c1eb'|cut -d"-" -f$i;done
1
  • You might have missed the part about "no external binaries".
    – nickgrim
    Sep 17, 2012 at 8:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.