-2

I have the following bash script.

while IFS= read -r filename;
  do [[ $(md5 path/to/"$filename-orig") = $(md5 path/to/"$filename") ]] || echo $filename differs;
  done < path/to/list-of-files-to-compare.txt

It's supposed to compare two files (by computing their MD5 hash digest) then report if they are different. It gets the files to compare from a list.

The problem is that if the file I am trying to read is at, say,

path/to/foo-orig.js

the script will look for the file at

path/to/foo.js-orig

and, obviously, this throws an error and fails.

How do I correct this bug in my script so that I handle the .js extension correctly?

Edit

TL;DR:

Given a string foo.bar how can I get foo-orig.bar?

Let Me Tink About It
  • 15,156
  • 21
  • 98
  • 207
  • Can you please rewrite your question from the scratch to something much, much smaller along the lines of: "Given a string `foo.bar` how can I get a string `foo-orig.bar`? – Micha Wiedenmann Nov 30 '18 at 07:50
  • @MichaWiedenmann: Thanks for the suggestion. Does the TLDR do the job? I wanted to keep the context in case that helps, but I do see the value in making the question shorter for clarity. So thanks. Does that do the trick? – Let Me Tink About It Nov 30 '18 at 07:54
  • If you ask for my opinion then I suggest you very much to change your question. I see SO question as reference question which should be as short as possible and as general as possible. (That is I don't think that OPs case should matter much.) But this is just my opinion yours might be different. – Micha Wiedenmann Nov 30 '18 at 07:56
  • On another note: I suggest you remove the reference to BASH from the title, see [this meta discussion](https://meta.stackexchange.com/questions/19190/should-questions-include-tags-in-their-titles). – Micha Wiedenmann Nov 30 '18 at 07:59

2 Answers2

1

If I understand you correctly you are really only asking: Given a string foo.bar how can I get a string foo-orig.bar? This can be done as:

$ f="path/to/foo.js"
$ echo "${f%.js}-bak.js"
path/to/foo-bak.js

It is documented under Parameter Expansion in man bash:

${parameter%word}
${parameter%%word}
Remove matching suffix pattern. The word is expanded to produce a pattern just as in pathname expansion. If the pattern matches a trailing portion of the expanded value of parameter, then the result of the expansion is the expanded value of parameter with the shortest matching pattern (the "%" case) or the longest matching pattern (the "%%" case) deleted. If parameter is @ or *, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with @ or *, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list.

Micha Wiedenmann
  • 19,979
  • 21
  • 92
  • 137
0

This example will handle all kind of extensions and even the case where there is no extension in $filename:

while IFS= read -r filename; do
   if [[ $filename =~ ^(.*)([.].*)$ ]]; then
       prefix=${BASH_REMATCH[1]}
       suffix=${BASH_REMATCH[2]}
   else
       prefix=${filename}
       suffix=''
   fi
   md5a=$(md5 -q "path/to/${prefix}-orig${suffix}")
   md5b=$(md5 -q "path/to/${filename}")
   [[ $md5a = $md5b ]] || echo $filename differs;
   unset md5a
   unset md5b
   unset prefix
   unset suffix
done < path/to/list-of-files-to-compare.txt

Not tested though. I just wrote it out of my head.

accdias
  • 5,160
  • 3
  • 19
  • 31