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?

5 Answers 5

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
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
5
  • line in the question is a filename.
    – Kusalananda
    Jun 28, 2018 at 7:24
  • @Kusalananda i thought it was a string, edited my answer for both the situations
    – Arushix
    Jun 28, 2018 at 7: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 Jun 28, 2018 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..." Jun 28, 2018 at 11:37
  • @glennjackman thanks for the suggestion, i did not considered that situation, added in my answer too :)
    – Arushix
    Jun 28, 2018 at 12:13
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.

1
  • simple but valuable, thank you :)
    – xeruf
    Feb 6, 2022 at 19:39
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)"
1
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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .