0
115:wc -l:find . -iname "*test*":find /tmp/ -iname "*test*"

I would like to parse the string above.

In my case, a string consists of 4 columns (every command has : separator) but it can be much longer. I want to "pull out" all the commands including initial number, starting with 115 and continuing with wc -l, -iname "*test*", find /tmp/ -iname "*test*" ... always without : separator.

My variable $var should get those values:

var= 115 , var= wc-l , var= find . -iname "*test*" , var= find /tmp/ -iname "*test*"

My code:

while read line;
 do
 while [[ $var -ne '0' ]];
   do
    var=$( echo $line | cut -d ':' -f$i )
    i=$( expr $i + 1 )
    echo $var
   done
done <$1

I read lines from file and with second while I cut columns until empty one. Obviously, there is something wrong because echo do not print anything.

  • 1
    Sounds a bit like you want us to do your homework. Can you elaborate on what you tried already? – Minix May 19 '15 at 20:56
  • Pardon me! I tried to cut column by column but result is just not satisfying. var=$( echo $line | cut -d ':' -f1-4 | tr ':' '\n' ) – ZeroZek May 19 '15 at 21:46
  • please elaborate on how your result was not satisfying and use the edit functionality to add it to the question. It will be easier to help you that way :) – Minix May 19 '15 at 21:56
  • 1
    I added some code :). Hope now is better to understand. Thank you! – ZeroZek May 20 '15 at 9:26
1

Here is your script fixed to work the way I think you meant it to work:

i=1     
while read line;                        
  do     
  while :; do 
    var=$( echo $line | cut -d ':' -f$i )                                   
    i=$( expr $i + 1 ) 
    [[ "$var" != "" ]] || break
    echo $var
  done     
done <$1

A couple of remarks:

  • i was not initialized
  • var was not initialized either, so the inner loop would not execute even once
  • I'm not sure what [[ $var -ne '0' ]] tests, but I think comparing $var to an empty string is better.
  • As a consequence, if there is an enpty field (i.e. two consecutive colons), this script will terminate there

A more robust way of doing the same thing is:

while read line; do
  num_fields=$(echo $line|awk -F':' '{print NF}')
  for (( i=1; i <= num_fields; i++ )); do
    var=$( echo $line | cut -d ':' -f$i )
    echo $var
  done
done <$1

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.