[string] How to split a delimited string into an array in awk?

How to split the string when it contains pipe symbols | in it. I want to split them to be in array.

I tried

echo "12:23:11" | awk '{split($0,a,":"); print a[3] a[2] a[1]}'

Which works fine. If my string is like "12|23|11" then how do I split them into an array?

This question is related to string unix awk split

The answer is


Actually awk has a feature called 'Input Field Separator Variable' link. This is how to use it. It's not really an array, but it uses the internal $ variables. For splitting a simple string it is easier.

echo "12|23|11" | awk 'BEGIN {FS="|";} { print $1, $2, $3 }'

I do not like the echo "..." | awk ... solution as it calls unnecessary fork and execsystem calls.

I prefer a Dimitre's solution with a little twist

awk -F\| '{print $3 $2 $1}' <<<'12|23|11'

Or a bit shorter version:

awk -F\| '$0=$3 $2 $1' <<<'12|23|11'

In this case the output record put together which is a true condition, so it gets printed.

In this specific case the stdin redirection can be spared with setting an internal variable:

awk -v T='12|23|11' 'BEGIN{split(T,a,"|");print a[3] a[2] a[1]}'

I used quite a while, but in this could be managed by internal string manipulation. In the first case the original string is split by internal terminator. In the second case it is assumed that the string always contains digit pairs separated by a one character separator.

T='12|23|11';echo -n ${T##*|};T=${T%|*};echo ${T#*|}${T%|*}
T='12|23|11';echo ${T:6}${T:3:2}${T:0:2}

The result in all cases is

112312

To split a string to an array in awk we use the function split():

 awk '{split($0, a, ":")}'
 #           ^^  ^  ^^^
 #            |  |   |
 #       string  |   delimiter
 #               |
 #               array to store the pieces

If no separator is given, it uses the FS, which defaults to the space:

$ awk '{split($0, a); print a[2]}' <<< "a:b c:d e"
c:d

We can give a separator, for example ::

$ awk '{split($0, a, ":"); print a[2]}' <<< "a:b c:d e"
b c

Which is equivalent to setting it through the FS:

$ awk -F: '{split($0, a); print a[1]}' <<< "a:b c:d e"
b c

In gawk you can also provide the separator as a regexp:

$ awk '{split($0, a, ":*"); print a[2]}' <<< "a:::b c::d e" #note multiple :
b c

And even see what the delimiter was on every step by using its fourth parameter:

$ awk '{split($0, a, ":*", sep); print a[2]; print sep[1]}' <<< "a:::b c::d e"
b c
:::

Let's quote the man page of GNU awk:

split(string, array [, fieldsep [, seps ] ])

Divide string into pieces separated by fieldsep and store the pieces in array and the separator strings in the seps array. The first piece is stored in array[1], the second piece in array[2], and so forth. The string value of the third argument, fieldsep, is a regexp describing where to split string (much as FS can be a regexp describing where to split input records). If fieldsep is omitted, the value of FS is used. split() returns the number of elements created. seps is a gawk extension, with seps[i] being the separator string between array[i] and array[i+1]. If fieldsep is a single space, then any leading whitespace goes into seps[0] and any trailing whitespace goes into seps[n], where n is the return value of split() (i.e., the number of elements in array).


echo "12|23|11" | awk '{split($0,a,"|"); print a[3] a[2] a[1]}'

should work.


I know this is kind of old question, but I thought maybe someone like my trick. Especially since this solution not limited to a specific number of items.

# Convert to an array
_ITEMS=($(echo "12|23|11" | tr '|' '\n'))

# Output array items
for _ITEM in "${_ITEMS[@]}"; do
  echo "Item: ${_ITEM}"
done

The output will be:

Item: 12
Item: 23
Item: 11

Please be more specific! What do you mean by "it doesn't work"? Post the exact output (or error message), your OS and awk version:

% awk -F\| '{
  for (i = 0; ++i <= NF;)
    print i, $i
  }' <<<'12|23|11'
1 12
2 23
3 11

Or, using split:

% awk '{
  n = split($0, t, "|")
  for (i = 0; ++i <= n;)
    print i, t[i]
  }' <<<'12|23|11'
1 12
2 23
3 11

Edit: on Solaris you'll need to use the POSIX awk (/usr/xpg4/bin/awk) in order to process 4000 fields correctly.


Joke? :)

How about echo "12|23|11" | awk '{split($0,a,"|"); print a[3] a[2] a[1]}'

This is my output:

p2> echo "12|23|11" | awk '{split($0,a,"|"); print a[3] a[2] a[1]}'
112312

so I guess it's working after all..


echo "12|23|11" | awk '{split($0,a,"|"); print a[3] a[2] a[1]}'

Examples related to string

How to split a string in two and store it in a field String method cannot be found in a main class method Kotlin - How to correctly concatenate a String Replacing a character from a certain index Remove quotes from String in Python Detect whether a Python string is a number or a letter How does String substring work in Swift How does String.Index work in Swift swift 3.0 Data to String? How to parse JSON string in Typescript

Examples related to unix

Docker CE on RHEL - Requires: container-selinux >= 2.9 What does `set -x` do? How to find files modified in last x minutes (find -mmin does not work as expected) sudo: npm: command not found How to sort a file in-place How to read a .properties file which contains keys that have a period character using Shell script gpg decryption fails with no secret key error Loop through a comma-separated shell variable Best way to find os name and version in Unix/Linux platform Resource u'tokenizers/punkt/english.pickle' not found

Examples related to awk

What are NR and FNR and what does "NR==FNR" imply? awk - concatenate two string variable and assign to a third Printing column separated by comma using Awk command line Insert multiple lines into a file after specified pattern using shell script cut or awk command to print first field of first row How to run an awk commands in Windows? Linux bash script to extract IP address Print line numbers starting at zero using awk Trim leading and trailing spaces from a string in awk Use awk to find average of a column

Examples related to split

Parameter "stratify" from method "train_test_split" (scikit Learn) Pandas split DataFrame by column value How to split large text file in windows? Attribute Error: 'list' object has no attribute 'split' Split function in oracle to comma separated values with automatic sequence How would I get everything before a : in a string Python Split String by delimiter position using oracle SQL JavaScript split String with white space Split a String into an array in Swift? Split pandas dataframe in two if it has more than 10 rows