LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   bash loops not behaving (https://www.linuxquestions.org/questions/linux-software-2/bash-loops-not-behaving-892712/)

timl 07-20-2011 07:39 AM

bash loops not behaving
 
Hi, I maintain a legacy system written in pascal (popular language in 70s/80s for the younger folk) and the operating system is VMS. These are largely irrelevant but you never know!

Recent changes have not been well coordinated and I am concerned that some dev code did not make it into the production area (there is no source control). As I maintain things remotely I don't want to spend all day on a VPN checking the code.

I have copied both trees to my laptop (Fedora 14) and I want to write a script which will simply loop through all directories and dump md5sums of all pascal files. I can then compare the contents of the 2 trees for differences. A complication is that some directories have sub directories so I need to search these also.

I have pasted the script so far as I have a problem. The first "for i in *" looks at all files in the top level. I then check if it is a directory (" if [ -d..."). If true then move to that level and check for any directories in the next level. Then check the pascal files in the next level directory.

What I find is that the script finds the first directory and navigates down. When it returns to the top level, it treats the next directory as a normal file and skips it. It only recognises the first directory as such.

Aha, how about I rename the first directory to something like "zzz" so the script will look at the 2nd directory first! Same thing, the "if" statement only recognises one directory as such and skips the rest.

I have tried to explain my problem the best I can. Simply, are there any issues relating to repeated use of "if [ -d"?

Alternatively, is there a simple linux tool which I can use to compare files in 2 trees and highlight the differences.

Thanks
#! /bin/sh
for i in *
do
echo 1 $i 5
if [ -d "$i" ]; then
echo 2 $i 5
cd $i
for j in *; do
if [ -d $j ]; then
cd $j
for k in *.pas; do
md5sum ${k}
md5sum ${k} >> csum
done
fi
done
fi
done

Snark1994 07-20-2011 08:15 AM

You should just be able to run:

Code:

diff dir1 dir2 -r
For me, this gives output like:

Code:

Only in dir1/A: file1
diff -r dir1/B/file2 dir2/B/file2
1c1
< FOO
---
> BAH
Only in dir2/C: file3


ntubski 07-20-2011 08:28 AM

The problem with the bash script is that you cd'd into the subdirectory but then didn't go back up. But you are better off using diff for this.

PS please put code inside code tags, like this:
Code:

[code] your code here [/code]

grail 07-20-2011 08:29 AM

Well diff would be the tool i would use to compare 2 files.

May I suggest as you are looking for files only that you use find to return all the files in one tree and then assuming the same format on the other structure simply compare.
Code:

#!/bin/bash

start_of_second_tree=/path/to/start/of/second/tree

while read -r PAS
do
    diff -q $PAS $start_of_second_tree/$PAS
done< <(find . -type f -name '*.pas')

So this assumes we are executing from with the top level of the first tree and should output something along the lines of:
Code:

Files ./first/tree/file1.pas and /second/tree/./first/tree/file1.pas differ
Well you get the idea.

Edit: hmmm .. or you could just do Snark's way ... live and learn :)

timl 07-20-2011 08:39 AM

well thanks all for the rapid response:

snark1994 solution seems simple and efficient
ntubski thanks for the code review. Doh!
grail I am not sure exactly how your code works but it gives me something to investigate

minnarky 07-20-2011 09:12 AM

diff -r may be what you are looking for

wow...didn't refresh and look how many responses beat me to the punch...


All times are GMT -5. The time now is 09:12 PM.