Issue in awk parsing under while loop

Hi

I am trying to parse a grep output using awk. It works fine individually and not working under the loop with variable name assigned.

cat > file.txt
dict=/dictr/abcd/d1/wq:/dictr/abcd/d2/wq:/dictr/abcd/d3/wq:

sample tried code

Nos=`grep -w "dict" file.txt | awk -F"=" '{print $2}' | awk -F":" '{print NF-1}'`
echo "$Nos"
while [ "$Nos" -ge 1 ]
do
sPath=`grep -w "dict" file.txt | awk -F"=" '{ print $2}' | awk -F":" '{ print $(echo "$Nos") }'`
echo "$sPath" 
if [[ -s "$sPath"/*12581.log ]]; then
    FileName=`ls  "$sPath"/*12581.log |head -1`
fi
  Nos=`expr $Nos- 1`
done
#echo "$FileName"

sample output

/dictr/abcd/d1/wq:/dictr/abcd/d2/wq:/dictr/abcd/d3/wq:
/dictr/abcd/d1/wq:/dictr/abcd/d2/wq:/dictr/abcd/d3/wq:
/dictr/abcd/d1/wq:/dictr/abcd/d2/wq:/dictr/abcd/d3/wq:

I know you said "[you're] trying to parse a grep output using awk", but what are you, ultimately, trying to accomplish. What's the end goal?

What's the result you expect out of this?

`grep -w "dict" file.txt | awk -F"=" '{ print $2}' | awk -F":" '{ print $(echo "$Nos") }'`

Hi

I want

echo "$sPath"

should produce the output

/dictr/abcd/d1/wq
/dictr/abcd/d2/wq
/dictr/abcd/d3/wq

OK, here the thing, AWK doesn't need the help of GREP , nor do you need to invoke AWK twice to achieve that result.

Consider the following:

awk -F: 'sub("^dict=", "") {for(i=1;i<NF;i++){print $i}}' file.txt
/dictr/abcd/d1/wq
/dictr/abcd/d2/wq
/dictr/abcd/d3/wq

Hi

What about assigning the output to a variable if certain file exists.

bash-3.00$ awk -F: 'sub("^dict=", "") {for(j=1;j<NF;j++) system("test -f " "$j"/*12581.log)==0 { print $j }}' file.txt
awk: syntax error near line 1
awk: bailing out near line 1
bash-3.00$ 

need to assign the output of awk to a variable for further processing. the following part of the previous code needs to be merged to assign.

if [[ -s "$sPath"/*12581.log ]]; then
    FileName=`ls  "$sPath"/*12581.log |head -1`
fi

Assigning to a variable:

sPath=$(awk -F: 'sub("^dict=", "") {for(i=1;i<NF;i++){print $i}}' file.txt)

What do you expect to be the result of this? What would it yield?

"$sPath"/*12581.log

i will be having files ending with *12581.log in only one of the returned path.
So i want to use that path for further processing.

simple terms awk will give three paths and definitely in one path *12581.log will be present.

If sPath contains three elements that would suggest an iteration.

for p in ${sPath[@]}; do
   # do something with $p
done

If $sPath/*12581.log could expand to multiple entries, that suggest another iteration.

for p in ${sPath[@]}; do
   for f in "$p"/*12581.log; do
       if [[ -s $f ]]; then
           # do something with $f a file that exist
       fi
   done
done

Now, consider this:

sPath=$(awk -F: 'sub("^dict=", "") {for(i=1;i<NF;i++){print $i}}' file.txt)
find $sPath -name '*12581.log' -type f

How about (ignoring the unproblematic "find: �dict�: No such file or directory" error message)

find $(tr '=:' ' ' < file.txt) -iname "*12581.log"

For your error in post#5:

Hi,

Can any one tell me whats wrong in my original posted code, since in my actual implementation i can not do awk exact match. Since the data will be having multiple lines of same match pattern. So i am using xmllint to get the desired tag values. Hence i am unable to use this code.

Please refer my initial post wherein i have mentioned only one line in the input. But actually it will be having multiple similar lines with different values under different xml tags.

cat > file.txt
<xml>
<a>
dict=/dictr/abcd/d1/wq:/dictr/abcd/d2/wq:/dictr/abcd/d3/wq:
</a>
<b>
dict=/dictr/abcd/d1/wqa:/dictr/abcd/d2/wqb:/dictr/abcd/d3/wqc:
</b>
</xml>

---------- Post updated at 10:01 PM ---------- Previous update was at 01:24 PM ----------

Some how i managed to attain the desired results...

The following comments explain part of what I believe is wrong with your script in post #1.

Presumably, the first part of your code:

Nos=`grep -w "dict" file.txt | awk -F"=" '{print $2}' | awk -F":" '{print NF-1}'`
echo "$Nos"

when given the above contents in file.txt will set Nos to:

/dictr/abcd/d3/wq
/dictr/abcd/d3/wqc

and print those results. You then start a while loop with an invalid test condition:

while [ "$Nos" -ge 1 ]

the test -ge operator compares two numeric values, but a variable containing two pathnames separated by a <newline> character is not a numeric value.

Then we move on to the last stage of the pipeline in the command substitution in the variable assignment:

awk -F":" '{ print $(echo "$Nos") }'

I have no idea what the intent of this code is, but what it does is a request to print the field whose field number is formed by concatenating the value of the awk variable named echo (which has not been defined in this script and, therefore, has an empty string value) and the literal string $Nos (shell variables are not expanded inside single-quoted strings). Since that concatenation does not produce a numeric value, trying to print the contents of the field number identified by a non-numeric value gives you a 2nd syntax error. And, if the script hasn't aborted yet from the two syntax errors so far, the shell variable sPath will be set to an empty string. That then leads to an if statement that tests whether or not there is a file matching the filename matching pattern /*12581.log and if there is exactly one file matching that pattern and has a size greater than zero. If more than one file is matched by that pattern, you have a 3rd syntax error (since that test only works with one operand to the test -s operator).

And, finally, after that if statement, you have another command substitution:

  Nos=`expr $Nos- 1

that is used to reset the value of the Nos shell variable to its current (non-numeric) value to one less than its current value (which is another syntax error) which, therefore, sets Nos to an empty string.

You also have unneeded uses of awk , cat , expr , and grep (some of which have already been commented on by others in this thread) but if given proper arguments, they might not do anything but waste system resources and slow down your script.