0

I am trying to create a diff file the following way:

hdiff.pl -nx $FILEDIR/*filename* *filename* > diff_*filename*

However I need to run this command on 150 different files to create 150 different diff files. I am attempting to write a script to execute that will create all of the files for me but I am not sure what to put so that the command is recursive and uses all of the files in the directory.

I tried making a script to execute but it is looking like I just have to write out every individual command and then execute the script.

Edit:

To clarify, I am trying to avoid writing 150 lines of this:

hdiff.pl -nx $FILEDIR/*filename1* *filename1* > diff_*filename1*
hdiff.pl -nx $FILEDIR/*filename2* *filename2* > diff_*filename2*
hdiff.pl -nx $FILEDIR/*filename3* *filename3* > diff_*filename3*
2
  • When you say *filename1*, do you mean that as a glob, or a standin for a specific filename? *s are shell syntax, so trying to use them as formatting is a fast route to confusion; *filename* isn't a generic "insert a filename here" signifier; instead, it means "insert a list of all the filenames that have 'filename' inside them here". Commented Mar 16, 2023 at 21:11
  • filename1 is just a placeholder. The real file names look more like this: T_FILE_NAME Commented Mar 16, 2023 at 21:57

3 Answers 3

1

It looks like you're after something along these lines:

for f in *filename*; do
  hdiff.pl -nx "${FILEDIR}/${f}" "${f}" > "diff_${f}"
done

Note that that expands one glob expression to get a list of subject files, and uses each one (in turn, via a loop) to form the names of the corresponding files in the command you want to run.

Sign up to request clarification or add additional context in comments.

2 Comments

As I read the question, finding the filenames to iterate over requires globing inside "$FILEDIR"`; so we probably need to be including it in the glob and then stripping it out, as opposed to globbing without it and then extending.
It's hard to be sure, @CharlesDuffy, but the example command in the question seems to assume that there are matching input files in the working directory and in $FILEDIR, in which case one can work from either set.
1

Using bash globbing with a loop and some bash parameter expansions:

#!/bin/bash

for f in "$filedir"/* ; do 
    hdiff.pl -nx "$f" "${f##*/}" > "diff_${f##*/}" ;
done

Comments

0

If you have them in two separate directories, you could try the following:

#!/bin/bash

set -e

SRCDIR=$1 # $FILEDIR/filename
DSTDIR=$2 # filename

for FILE in $1/*; do hdiff.pl -nx $1/$FILE $2/$FILE > diff_$FILE ; done

Save as rundiff.sh and then you could simply $ ./rundiff.sh directory1 directory2

You may want to do some extra tweaking to the above if you want to print each file name while processing, and sanity checking inputs.

5 Comments

set -e -- so as soon as one file fails we want to stop there and not process any more?
(if that's what we really want, think about putting an explicit || exit after the failing command to make it clear to the reader; explicit error handling also avoids all the implicit, surprising behavior described in BashFAQ #105)
diff_$FILE looks odd.
@Cyrus, ...the only thing obviously wrong with diff_$FILE is that it'll have the directory name in it, as opposed to "diff_${FILE##*/}"
(of course, one can also argue that using all-caps names for application-defined variables is obviously wrong in and of itself, contravening black-letter POSIX specifications)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.