LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Using variable to store command lines in a pipeline? (https://www.linuxquestions.org/questions/programming-9/using-variable-to-store-command-lines-in-a-pipeline-785409/)

zizou86 01-28-2010 12:47 PM

Using variable to store command lines in a pipeline?
 
Hi,

Was trying to write a shell script that has if conditional statements to decide different arguments for a command.

Basically:

Code:

if [ "$1" = 1 ]
then
{
        sortarg=$("sort")
}
elif [ "$1" = 2 ]
then
{
        sortarg=$(echo "sort -k2 -t :")
}
fi

cat Cars.txt | "$sortarg"

However, I keep getting the "sort -t : Command not found" error for the 2nd option. My sort command has been verified to work if I hard code the entire sort command line. ie.

Code:

cat Cars.txt | sort -k2 -t :
The sort is working fine for the first option.

I have tried many different ways of phrasing the whole sort line in $sortarg but to avail. The reason I want to do this is due to the fact that the cat line is part of a very big loop, and different sorting options are available to the user. If I do not store the whole sort command line in a variable, I will have to copy-paste the whole chunk of code a few times for each sorting option.

Please assist.

TIA.!

catkin 01-28-2010 01:06 PM

Code:

if [ "$1" = 2 ]
then
        sortarg="-k2 -t :"
fi

cat Cars.txt | sort $sortarg

BTW, in bash, [[ <test expression> ]] is better than [ <test expression> ] for reasons explained here.

EDIT: the reason it was failing in the second case is that the double quotes around "$sortarg" makes it a single "word" so the shell was looking for command called "sort -k2 -t :" rather than the sort command with options. You could fix the script by removing the double quotes but the above is simpler.

SethsdadtheLinuxer 01-28-2010 01:10 PM

take the " off of "$sortarg".

tuxdev 01-28-2010 01:48 PM

The BashFAQ has an entry on this exact issue:
http://mywiki.wooledge.org/BashFAQ/050

zizou86 01-29-2010 06:54 AM

Hi all,

Thanks for the great help thus far. The original program worked great! I tried to add some more stuff to this.

Code:


if [ "$1" = 1 ]
then
{
        sortarg=$("sort")
}
elif [ "$1" = 2 ]
then
{
        sortarg=$(echo "sort -k2 -t :")
}
fi

while read inputline
        do
                col1="$(echo $inputline | cut -d: -f1)"
                col2="$(echo $inputline | cut -d: -f2)"
                col3="$(echo $inputline | cut -d: -f3)"
                col4="$(echo $inputline | cut -d: -f4)"       
                col5="$(echo $inputline | cut -d: -f5)"       
               
        done < Cars.txt | $sorter

However, this does not seem to work. I had already verified that my sort commands worked via "cat Cars.txt | sort sort -k2 -t : " in the shell prompt. The reason I am adding this in is to split the data into different columns.

However, once inside the program it does not seem to work. Only good old sort without any arguments worked.

Am I missing something here?

Thanks.

catkin 01-29-2010 07:14 AM

$sorter is not given a value in the code snippet you posted.

A useful debugging technique is to add lines showing the value of variables, for example
Code:

while read inputline
        do
                echo "DEBUG: inputline: '$inputline'"
                col1="$(echo $inputline | cut -d: -f1)"
                echo "DEBUG: col1: '$col1'"
                [snip]

The purpose of the single quotes is to show any leading or trailing whitespace in the value of the variable.

BTW, you do not need to echo strings to assign them to variable, you can assign them directly, for example
Code:

sortarg='sort'
You are, of course, free to ignore any suggestions given here but have you understood how much simpler the code I suggested above is than the code you are using?

zizou86 01-29-2010 10:20 AM

Code:


        if [ "$1" = 1 ]
        then
        {
                sorter=""
        }
        elif [ "$1" = 2 ]
        then
        {
                sorter="-k2 -t :"
        }
        fi

        cars=$(cat Cars.txt | sort $sorter)
        echo "$cars" > Cars.txt

        while read inputline
        do
                col1="$(echo $inputline | cut -d: -f1)"
                col2="$(echo $inputline | cut -d: -f2)"
                col3="$(echo $inputline | cut -d: -f2)"
                col4="$(echo $inputline | cut -d: -f2)"
                col5="$(echo $inputline | cut -d: -f2)"

                printf "%-45s %-20s %-10s %-5s %-8s %-10s\n" "$col1" "$col2" "$col3" "$col4" "$col5" "$total_sales"
        done < Cars2.txt # display in sorted format!
        ##done < Cars.txt | sort $sorter  ###THIS WAS ORIGINAL COMMAND THAT DO NOT WORK!

Output:

Car 1 Mitsubihi 13 22 50

Hence, $col1 to 5 will hold the value of the respective field in each row, looping till the whole file is complete.

Code:

Data of Cars.txt (quite a few rows, delimited by colons):

format: Car model:Manufacturer:price:no. sold:no. left

Car 1:Mistubishi:13:22:50
Car 5:Toyota:23:3:2



Catkin,

My apologies for ignoring your earlier post about leaving the sort command out of the string. I did not really notice the difference at first and hence did not carry out your suggestion.

Basically, what this do was to grab the data off Cars.txt and display out all rows in a format. What I wanted to do was to add a "sorting function" so you can sort by Car name, brand, price, etc. So far, I have only added 2 of these.

My original intention was to dynamically assign $sorter value. Hence, the user will select what to sort with, and $sorter will hold the relevant sort command's arguments for that particular selection. However, apparently there is some form of logic error in this as this does not work in the loop. I have verified that this method does work provided if I simply used:

Code:

cat BookDB.txt | sort $sorter
Hence, the interim solution I employed is to sort the file first, store it inside another file (the read line do while loop refuse to let me throw in a variable, only wants a file) and let the sorted file display out the contents. Not very elegant, but at least its working somewhat.

However, I would appreciate if any of you experienced users will care to break down and explain why my intial method do not work? (The intial method is in the code with a ###THIS WAS ORIGINAL COMMAND THAT DO NOT WORK! comment.

Thank you.


All times are GMT -5. The time now is 01:19 PM.