Parsing a flat file using shell script

5,693

Solution 1

I'm not really sure if I get the point of your question.

At first: IFS is a variable, that contains a separator, like a tab, a space or something. By default it contains a space, tab and newline.

EDIT: from a for-loop loop to a while-loop, suggested by terdon

while read line
do
        echo $line|cut -d\: -f2
done < /path/to/file.csv

This generates this output:

blala
blala
***.***.**.**

You can do this with a while-loop as well, in personal I just like the for-loop here more.

What is the loop doing? At first, the loop reads the first line of the file.csv and saves it to the variable "line".

Inside the loop we echo the variable $line and cut it into peaces. We cut it with the delimiter (-d) ":", because in youre file.csv there is always a ":" between the identifier and the value. with the field-indicator (-f) we only want to show us the field 2 (-f2). The for-loop ends when the file.csv has no more lines.

For more informations see the man page of cut(1).

Solution 2

It may be tempting to use eval, but as passwords can contain arbirary chars (which could/would be executed as code, it makes it risky; bordering on a plain-and-simple: "Don't do it!".
This works - using arrays.

Contents of test file

User:blala
Pass:blala with    spaces: and colons: and $PATH
IP:***.***.**.**

set -f                          # disable globbing
IFS=$'\n'                       # 'word' split only at newline char
value=($(sed 's/:/\n./' file))  # '.' to cater for empty value fields

echo user="${value[1]/./}" 
echo pass="${value[3]/./}" 
echo   ip="${value[5]/./}"

Output:

user=blala
pass=blala with    spaces: and colons: and $PATH
ip=***.***.**.**
Share:
5,693

Related videos on Youtube

user112534
Author by

user112534

Updated on September 18, 2022

Comments

  • user112534
    user112534 almost 2 years

    I have a file like in following format

    User:blala
    Pass:blala
    IP:***.***.**.**
    

    I tried with IFS but it is not working

    input="/path/to/your/input/file.cvs" 
    while IFS=',' read -r f1 f2 f3 f4 f5 f6 f7 
    do 
      echo "$f1 $f2 $f3 $f4 $f5 $f6 $f7" 
    done < "$input"
    

    I want to get User, Pass, IP values in my shell script .

    Please help.

    • taliezin
      taliezin about 9 years
      Did you try anything?
    • taliezin
      taliezin about 9 years
      You can edit your question with this info and what you are trying to achieve, so people can see what you have tried and will be able to help you.
    • G-Man Says 'Reinstate Monica'
      G-Man Says 'Reinstate Monica' about 9 years
      Rather than just copying some other command that you saw somewhere, I suggest that you look at bash(1) and/or other bash (or Bourne shell) documentation (try searching this site), and see how IFS= is supposed to work.  Hint: IFS=',' is not a magic bullet that solves all problems.
  • Peter.O
    Peter.O about 9 years
    By default, $IFS contains a space and a tab and a newline
  • quenia
    quenia about 9 years
    true. I'll edit it!
  • Anthon
    Anthon about 9 years
    Welcome to U&L and thanks for your answer. Please (re-)read the help->tour especially the part about chit-chat. Greetings are inappropriate on this Q&A site and your name is already below the answer based on your profile
  • Peter.O
    Peter.O about 9 years
    @StéphaneChazelas - I've added set -f - thanks
  • terdon
    terdon about 9 years
    You may like for loops more, but I'm afraid they're very simply wrong here. Your answer will break if there is any whitespace on the line. There is basically never good reason to use for i in $(cat file). You should always use while read i; do ... done < file instead.
  • quenia
    quenia about 9 years
    I never really thought about the different behaviour of a for and a whileloop. for this it works at least - I but your comment to my answer.
  • Peter.O
    Peter.O about 9 years
    @StéphaneChazelas - thanks again - fixed for empty 'value' fields.