6

I am using awk to split a string into array using a specific delimiter. Now, I want to perform some operation on each element of the array.

I am able to extract a single element like this:

#! /bin/bash

b=12:34:56
a=`echo $b | awk '{split($0,numbers,":"); print numbers[1]}'`
echo $a

I want to do something like this:

#! /bin/bash

b=12:34:56
`echo $b | awk '{split($0,numbers,":");}'`
for(i=0;i<length(numbers);i++)
{
   // perform some operation using numbers[i]
}

how would I do something like this in bash scripting?

1
  • as said below you really don't need awk here but if you want to use "back in the shell" a result produced by awk you'll have to output it from within awk ; for example numbers=$(echo...|awk '{split(...);print numbers}'); for n in $numbers; do ... done (which is simpler than using indices but you can also do numbers=($(...)); for((i=0; i<${#numbers};++i)); do echo ${numbers[i]} ; done. HTH Commented Jul 17, 2020 at 17:33

5 Answers 5

20

None of these answers used awk (weird). With awk you can do something like:

echo 12:34:56 | awk '{split($0,numbers,":")} END {for(n in numbers){ print numbers[n] }}'

replacing print numbers[n] with whatever it is you want to do.

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

3 Comments

They don't use awk because there's no reason to start an external program to do something bash can already do.
But if the question is "how to do this in awk" and none of the answers involve awk, the question isn't really answered. The result is that Google searches return a useless result for anyone trying to figure out how to do exactly this in awk (which may be useful because they're doing other things in awk already and just want to add this one thing).
I indeed came to this question looking for exactly and specifically how to do it in awk. So this answer was the only answer for me.
17

You don't really need awk for that, bash can do some string processing all by itself.

Try:

b=12:34:56
for element in ${b//:/ } ; do
  echo $element
done

If you need a counter, it's pretty trivial to add that.

See How do I do string manipulations in bash? for more info on what you can do directly in bash.

Comments

6
b=12:34:56
IFS=:
set -- $b
for i; do echo $i; done

This does not contain bashisms but works with every sh.

2 Comments

Be aware that this overwrites the positional arguments in $@, so you'll need to save them as necessary before running the set command.
of course; usually, I put complex tasks in functions which have their own $@ context (saving "$@" is too ugly and nearly impossible without bashisms).
2

The bash read command can split a string into an array by itself:

IFS=: read -a numbers <<< "$b"

To see that it worked:

echo "Hours: ${numbers[0]}"
echo "Minutes: ${numbers[1]}"
echo "Seconds: ${numbers[2]}"

for val in "${numbers[@]}"; do
   seconds=$(( seconds * 60 + $val ))
done

Comments

1

Another neat way, not using awk, but build-in 'declare':

b=12:34:56

# USE IFS for splitting (and elements can have spaces in them)
IFS=":"
declare -a elements=( $b )
#show contents
for (( i=0 ; i < ${#elements[@]}; i++ )); do
    echo "$i= ${elements[$i]}"
done

1 Comment

This doesn't work in all cases; leaving b unquoted leaves it subject to pathname expansion as well as word-splitting.

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.