0

I have a program that reads two words in command line:

#!/bin/bash

if [[ "$1" != "" && "$2" != "" ]]; then
    java -Xmx1024m -cp lib/*:esalib.jar clldsystem.esa.ESAAnalyzer "$1" "$2"
else
    java -Xmx1024m -cp lib/*:esalib.jar clldsystem.esa.ESAAnalyzer
fi

I replaced this code to read from a file line by line, this is an example of the file that i must read:

vehicle car
computer program
volley ball

the code read each line and affect each word to a variable, the problem is in the splitting process of each line so it affec to $var1 and $var2 the same word

#!/bin/bash

while read ligne
do
var1=$(echo $ligne | cut -f1 -d-)
var2=$(echo $ligne | cut -f2 -d-)

if [[ "$var1" != "" && "$var2" != "" ]]; then
    java -Xmx1024m -cp lib/*:esalib.jar clldsystem.esa.ESAAnalyzer "$var1" "$var2"
else
    java -Xmx1024m -cp lib/*:esalib.jar clldsystem.esa.ESAAnalyzer
fi
done < mm.txt

but the new code don't give results

DiligentKarma
  • 5,198
  • 1
  • 30
  • 33
Chedi Bechikh
  • 183
  • 3
  • 13
  • 2
    have you debugged your script? Do the values $var1 and $var2 hold the correct values? – glenn jackman Jan 14 '16 at 15:49
  • 2
    Please provide a sample contents of mm.txt – Mad Physicist Jan 14 '16 at 16:10
  • @MadPhysicist: eac line contain 2 words, it work but the program use the first word for var1 and var2, i think the problem in the split of the line, mm.txt can contain car vehicle – Chedi Bechikh Jan 14 '16 at 16:26
  • Add `set -x` to the top of the script and show the output from running it. Then show the contents of `mm.txt` (or an equivalent dummy file is the contents are sensitive). – Etan Reisner Jan 14 '16 at 16:57
  • @ChediBechikh. Provide all necessary information in your question rather than hand waving it away. You have a good question, but the way you are asking it is very sloppy, which is why it is about to be closed before you get any kind of answer. – Mad Physicist Jan 14 '16 at 17:03
  • @MadPhysicist: sorry i made the changes in the question – Chedi Bechikh Jan 14 '16 at 17:12
  • Thanks. That helps. Now temporarily replace `java -X... "$var1" "$var2"` with just `echo "$var1" "$var2"` and `java -X...Analyzer` with `echo "No args found"` and tell us what happened. – Mad Physicist Jan 14 '16 at 17:19

2 Answers2

3

You can read two variables with read. They are separated by any IFS character, which defaults to space and tab (and newline, but read stops there anyway).

while read -r var1 var2; do
    if [[ "$var1" != "" && "$var2" != "" ]]; then
        java -Xmx1024m -cp lib/*:esalib.jar clldsystem.esa.ESAAnalyzer "$var1" "$var2"
    else
        java -Xmx1024m -cp lib/*:esalib.jar clldsystem.esa.ESAAnalyzer
    fi
done < mm.txt

The -r switch to read prevents it from parsing backslash escapes, which is often undesirable behaviour.

user3035772
  • 171
  • 5
1

Here is how you would debug your program:

#!/bin/bash

while read ligne
do
var1=$(echo $ligne | cut -f1 -d' ')
var2=$(echo $ligne | cut -f2 -d' ')

if [[ "$var1" != "" && "$var2" != "" ]]; then
    echo "$var1" '|' "$var2"
    #java -Xmx1024m -cp lib/*:esalib.jar clldsystem.esa.ESAAnalyzer "$var1" "$var2"
else
    echo "Vars Not Found"
    #java -Xmx1024m -cp lib/*:esalib.jar clldsystem.esa.ESAAnalyzer
fi
done < mm.txt

Running this gives the following output:

vehicle car | vehicle car
computer program | computer program
volley ball | volley ball

This means that your cut command is not correct. You have a few options to fix it:

  1. Use multi-variable read as user3035772 pointed out. This is less flexible because it relies on the separator being $IFS, which you are implicitly not agreeing to.
  2. Fix the delimiter in mm.txt to be - as the -d- flag of the cut command requires: vehicle-car computer-program volley-ball
  3. Fix the cut command to require a space delimiter as you have in mm.txt: cut -f1 -d' '.
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
  • "This is less flexible[...]" -- It's not. You can change the delimiter by setting `IFS`, so to split on colons for example you would prefix the `read` command with `IFS=:`. This is no less flexible than passing something to the `-d` argument to `cut`. – user3035772 Jan 15 '16 at 11:17
  • @Mad Pyhsicist : thank you very much, now i know how to debug the code, and the solutions 2 and 3 are both correct and works well – Chedi Bechikh Jan 15 '16 at 11:20
  • @user3035772 I disagree. Messing with IFS is almost always the least desirable path when there is an alternative. In the best case, it introduces extra lines where you set and unset it. In the worst case it introduces the possibility of hidden side effects since so many programs depend on it. – Mad Physicist Jan 15 '16 at 13:00
  • @MadPhysicist It does not introduce those lines nor those side effects. In a command structured like `IFS=: read -r var1 var2`, the IFS change _only_ affects the read builtin. Further, the possibility of side effects affecting launched programs is greatly exaggerated - that would only be a concern if you `export`ed `IFS`, which is a huge mistake in the first place. – user3035772 Jan 15 '16 at 14:46
  • @user3035772. Your solution is perfectly valid and more elegant than calling `cut` twice. I am in not trying to deny that. Your command structure is definitely the best way of modifying IFS, but keep in mind that IFS also affects arrays and a couple of other things in the shell that depend on spacing. The main problem here was actually that the OP did not properly debug a simple issue. – Mad Physicist Jan 15 '16 at 16:46