0

From the following link, I tried to use the following solution to compare a group of source files (here fortran90 = *.f90).

To do this and see the source which are different, I have put into my ~/.bashrc :

function diffm { for file in "$1"/"$2"; do diff -qs "$file" "$3"/"${file##*/}"; done ;}

But unfortunately, if I am in the current directory for argument $1, i.e by execute :

$ diffm . '*.f90' ../../dir2

The result is : impossible to access to './*.f90'. However, the sources *.f90 exist but wildcards are not taken into account.

Surely a problem with double quotes on arguments of my function ($1, $2, $3)?

More generally, this function doesn't work well.

How can I modify this function in order to make it work in all cases, even being in the current directory "." for the first argument $1 or the third $3?

halfer
  • 19,824
  • 17
  • 99
  • 186

2 Answers2

1

If i understood what you are trying to do, this should work

diffm () {
    dir="$1"; shift
    for file in "$@"; do
        filename=$(basename "$file")
        diff -qs "$file" "$dir/$filename"
    done
}

Usage

diffm ../../dir2 ./*.f90
Ivan
  • 6,188
  • 1
  • 16
  • 23
0

Filename generation does not occur within quotes. Hence, you pass the literal string *.f90 to the function, and this string is used there literally too. If you know for sure that there is exactly one f90 files in your directory, don't use quotes and write

diffm . *.f90 ../../dir2

Things get ugly if the file name has a space embedded (which, BTW, is one reason why I prefer Zsh over bash - you don't have to care about this in Zsh). To deal with this case, you could do a

myfile=*.f90
diffm . "$myfile" ../../dir2

But sooner or later, you will be bitten by the fact, that for whatever reason, you have more than one f90 file, and your strategy will break. Therefore, a better solution would be to use a loop, which also works for the border case of having only one file:

iterating=0
for myfile in *.f90
do
    if ((iterating == 0))
    then
      ((iterating+=1))
      diffm . "$myfile" ../../dir2
    elif [[ ! -f $myfile ]]
    then
      echo "No files matching $myfile in this directory"
    else
      echo "ERROR: More than one f90-file. Don't know which one to diff" 1>&2
    fi
done

The elif part just cares for the case that you don't have any f90 files. In this case, the loop body is executed once, and myfile contains the wildcard pattern.

user1934428
  • 19,864
  • 7
  • 42
  • 87
  • Thanks for your quick answer. Is there a way to keep my original bash function (into my first post) and find a way to have an argument which represents actually the wildcard of different files with the same extension, here a list of Fortran90 files : I would like to generalize it to different extensions, that's why I would like to convert `*.f90` into a shell script argument : in my original post, this is the argument `$2` but double quote it doesn't seem to be enough. Regards –  Feb 20 '20 at 21:27
  • Fixed by simply doing : `for file in "$1"/$2; do diff -q "$file" "$3"/"${file##*/}"; done ;` –  Feb 20 '20 at 21:42
  • Next step : find a way to get rid of the prresence or not of slash in the names of the 2 directories. –  Feb 20 '20 at 21:46
  • Please start a new thread on SO if you have a new question. You can enter a link to this question if you think it helps in understanding. – user1934428 Feb 21 '20 at 07:13