5

I need to split a line with two string separated by an space like: key value.

I've tried:

key=$(awk -FS=" " {print $1} line)
value=$(awk -FS=" " {print $2} line)

But I'm getting:

awk: line 2: missing } near end of file

Any ideas?

Jordi
  • 325
  • 5
  • 10

5 Answers5

6

An awk script on the command line should be single quoted:

awk -F ' ' '{ print $1 }' filename

Notice the single quotes around { ... }, and also that the correct way to set FS is through -F, or through -v FS=... or in a BEGIN block, but not with -FS=....

Your command, the way you have written it, also assumes that line is a file name.


If $line is a string with a single space in it, you can separate it into two strings with

first_part=${line% *}   # removes the space and everything after it
second_part=${line#* }  # removes the space and everything before it

Likewise, if $line is a string with a = in it:

first_part=${line%=*}   # removes the = and everything after it
second_part=${line#*=}  # removes the = and everything before it
Kusalananda
  • 333,661
3

You can also use an array for splitting a line on spaces:

if line is a string

  arr=($line)
  key="${arr[0]}"
  value="${arr[1]}"

Note:- If the first word of $line is * then the arr array will contain all the filenames in the current directory. So to be on the safe side and avoid such situations , use

set -f; arr=($line); set +f key="${arr[0]}" value="${arr[1]}"

If line is file

while read -r words
do
  set -- $words
  key=$1
  value=$2
done < line
Arushix
  • 1,290
  • line in the question is a filename. – Kusalananda Jun 28 '18 at 07:24
  • @Kusalananda i thought it was a string, edited my answer for both the situations – Arushix Jun 28 '18 at 07:30
  • In the first snippet, you are leaving the variable unquoted to employ word splitting. However you are also subject to filename expansion. If the first word of $line is * then the arr array will contain all the filenames in the current directory. You will have to set -f; arr=($line); set +f – glenn jackman Jun 28 '18 at 11:30
  • @Kusalananda, I wouldn't assume that it's a file, given the apparent experience level of the question. I would put more trust in the words: "I need to split a line..." – glenn jackman Jun 28 '18 at 11:37
  • @glennjackman thanks for the suggestion, i did not considered that situation, added in my answer too :) – Arushix Jun 28 '18 at 12:13
1

You can easily achieve this, without using awk, that is inteded for more complex data manipulation. cut bash command is all you need.

key="$(echo "$line" | cut -d ' ' -f 1)"
value="$(echo "$line" | cut -d ' ' -f 2)"
Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
Gio G.
  • 31
1

read

Just use read:

read key value

Everything before the first space on the line goes into key and everything after it (including any additional spaces) goes into value.

0

You can use the shell's parameter expansion facilities instead of calling out to an external program:

key=${line%% *}     # from the end remove the longest string matching
                    # a space followed by any characters

value=${line#* }    # from the start remove the shortest string matching
                    # any characters followed by a space
glenn jackman
  • 85,964