1

bash shellscript for loop two variables with input from two files

I have a file1:

I need to compare usedmem(column5)from file2 with free memory(column4) from file1. If free memory(column4) from file1 is greater than usedmem(column5)from file2. The output should be VM(column2) from file2 can be relocated to storage(column1) in file1. Files are sorted in descending order

storage,totalmem,usedmem,freemem

0843,524230,241374,282856  
0867,524230,253339,270891  
0842,524230,291427,232803  
0868,262086,48660,213426    
0849,524230,335445,188785  
0844,524230,335446,188784  
0860,524230,354981,169249  
0855,524230,354984,169246  
0862,524230,354985,169245  
0853,524230,354986,169244  
0850,524230,411733,112497  
0857,524230,411734,112496  
0841,524230,411734,112496  
0839,524230,411735,112495  
0848,524230,411736,112494  
0851,524230,411737,112493  

file2

storage, vm ,rack,usedcpu,usedmem,type  
0839,x0aaa05,US1 DA12,4,78851,FA  
0839,x0aaa01,US1 DA12,5,10243,OIM  
0839,x0aaa03,US1 DA12,6,4099,OHS  

Desired output -

significant memory does not exist in 0843 to relocate x0aaa06  
x0aaa05 can be relocated to 0867  
x0aaa01 can be relocated to 0842  
x0aaa03  can be relocated to 0868  

I have been trying to use for loop to pass something like

for i in `cat file2|wc -l`  
do  
   j=`cat  file1|cut -d, -f4`  
   m=`cat  file2|cut -d, -f5`  
   file1_dom=`cat  file1|cut -d, -f1`  
   file2_vm=`cat  file2|cut -d, -f2`  
        if [[ `${j} -gt ${m}` ]]  
        then  
             echo ${file2_vm} can be reclocated to ${file1_dom}  
        fi  
done    

output - erroring out

-bash: 282856: command not found

example 2-

set -- $( cat file1|cut -d, -f4 )  
for i in `cat file2|cut -d, -f5`  
do  
   if [[ $1 -gt $i ]]  
   then  
       echo $1  can be relocated to $i  
   fi  
done  

Output -

282856 can be relocated to 78851  
282856 can be relocated to 10243  
282856 can be relocated to 4099    
  • please, take a look at the editing help, especially the first point about code block formatting. Then take some time to edit the formatting of your post to make the question more readable. Also, there's no need to use shorthand for words like "output" (which I suppose you mean with "o/p"). The bits are cheap enough to spell it out, and the question is more understandable without uncommon abbreviations. – ilkkachu Dec 15 '18 at 15:06
  • Also please explain (in words) the logic applied to combine both files in order to create the output. – nohillside Dec 15 '18 at 15:09
  • I need to compare usedmem(column5)from file2 with free memory(column4) from file1. If free memory(column4) from file1 is greater than usedmem(column5)from file2. The output should be VM(column2) from file2 can be relocated to storage(column1) in file1. – neha dhawan Dec 15 '18 at 15:15
  • formatted code as well and have rewritten bits as suggested – neha dhawan Dec 15 '18 at 15:16
  • If I understand correctly, ALL freemem entries in file1 are greater than ALL usedmem entries in file2. So - should the output have 16 * 3 = 48 lines reporting all VMs to be relocatable? – RudiC Dec 15 '18 at 19:10
0
for i in `cat file2|wc -l`  
do  
   j=`cat  file1|cut -d, -f4`  
   m=`cat  file2|cut -d, -f5`  
   file1_dom=`cat  file1|cut -d, -f1`  
   file2_vm=`cat  file2|cut -d, -f2`  
        if [[ `${j} -gt ${m}` ]]  
        then  
             echo ${file2_vm} can be reclocated to ${file1_dom}  
        fi  
done    

Several issues I see with your code fragment:

  • Don't use backticks to start sub-shell, they've been deprecated for some time. Prefer the $(cmd) syntax.
  • It's unnecessary to write cat file2 | wc -l for example, wc -l file2 is shorter and more efficient. (No need to start cat, pipe its stdout to wc, etc.)
  • You should always, always, always quote all variable substitutions unless you want them to be subject to word splitting and globbing. I'm referring to unqouted ${file1_dom}. Also, it's unnecessary to write ${file1_dom}, $file1_dom would be preferred (the ${...} syntax offers some other goodies which are unnecessary here).
  • Likewise, you should always prevent common scripting errors by adding -eu to the interpreter line (shebang) of your scripts.
  • You don't need to use [[ for simple numerical comparisons, [ is sufficient.
  • The bug is probably in the comparison: ${j} -gt ${m} is surrounded by backticks and hence executed in a subshell, so that the value of j is taken as command name. (That's where the message comes from.) You want something like if [ "$j" -gt "$m" ]; then ..., applying all of the rules above.

If you choose to rewrite your script in accordance with these rules, please add it to your original post, so that others can benefit from seeing that correct scripting makes difference.

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.