0

I want to read a text file and split it's defined content as a key value pair. Content are multiple lines with key&value. Where key wont have spaces, so first space splits the key and value. but the value may have single or multiple or leading and trailing spaces. My scripts works fine with one flaw, that it removes all multi spaces. I want my value exactly how it mentioned in the file.

core script:

#!/bin/bash
input="./inp.txt"
while IFS= read -r line
do
    parts=($line)
    key=${parts[0]}
    value=${parts[@]:1:${#parts[@]}}
    echo .
    echo "Key: [$key]"
    echo "Value: [$value]"
    echo .
done < "$input"

input file (inp.txt):

KEY1 VAL1
KEY2   VAL2 has space & multi  spaces &    leading & trailing spaces.  
KEY3 VAL3
KEY4 VAL4
KEY5 VAL5

output:

Key: [KEY1]
Value: [VAL1]
.
.
Key: [KEY2]
Value: [VAL2 has space & multi spaces & leading & trailing spaces.]
.
.
Key: [KEY3]
Value: [VAL3]
.
.
Key: [KEY4]
Value: [VAL4]
.
.
Key: [KEY5]
Value: [VAL5]

expected: (Check KEY2-VALUE2)

Key: [KEY1]
Value: [VAL1]
.
.
Key: [KEY2]
Value: [  VAL2 has space & multi  spaces &    leading & trailing spaces.  ]
.
.
Key: [KEY3]
Value: [VAL3]
.
.
Key: [KEY4]
Value: [VAL4]
.
.
Key: [KEY5]
Value: [VAL5]

2 Answers 2

1

You could use standard POSIX parameter expansions ${parameter%%word} to remove the longest trailing substring and ${parameter#word} to remove the shortest leading substring:

#!/bin/bash
input="./inp.txt"
while IFS= read -r line
do
    key=${line%% *}
    value=${line#* }
    echo .
    echo "Key: [$key]"
    echo "Value: [$value]"
    echo .
done < "$input"
0

You can use sed on $line to delete KEY, its number and the first space instead of outputting each element of $parts:

#!/bin/bash
input="./inp.txt"
while IFS= read -r line
do
    parts=($line)
    key=${parts[0]}
    value=$(echo "$line" | sed 's/KEY[[:digit:]]*[[:space:]]//')
    echo .
    echo "Key: [$key]"
    echo "Value: [$value]"
    echo .
done < "$input"
3
  • For example only, i made key names ending with number. But in actual requriement, it might be a simple KEY with out a number. So I need to relay on first space only. to split the Key and rest all values.
    – Kaymatrix
    Dec 22, 2021 at 2:33
  • The regular expression will still match on a KEY without a number since the * token matches zero or more digits.
    – Stephan
    Dec 22, 2021 at 2:41
  • A simpler and more flexible regex operation might be: sed 's/^[^ ]* //' - "beginning of line"+"zero or more occurrences of any character but a space"+"space".
    – FelixJN
    Dec 22, 2021 at 10:08

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.