1

I've got the below simple script that calls an external script with a number of filenames and arguments of either a delimiter or a set of cut positions. My question: is there a way to make the filename 'dynamic using wildcards' in the sense that the directory will always contain those filenames but with extra text on either end? But the script can do some sort of match up to get the full filename based on a 'contains'.

current /release/ext/ directory contents:

2011storesblah.dat
hrlatest.dat
emp_new12.txt

ie the directory contains these files today (but next week the filenames in this directory could have a slightly different prefix. eg:

stores_newer.dat
finandhr.dat
emps.txt

Script:

 #!/bin/bash
    FILES='/release/ext/stores.dat "|"
    /release/ext/emp.txt 1-3 4-11 15-40
    /release/ext/hr.dat "|" 2'
    for f in $FILES
    do
        echo `sh myexternalscript.sh $f`;
    done

Note: there is no need to handle a scenario where the file in my script matches more than 2 files in the direc (it will always only match one). Also it only can match the file types that are specified in the script. Also, I don't need to search recursively, just needs to look in the /release/ext/ directory only. I'm running SunOS 5.10.

1
  • If you are running SunOS 5.10, why did you tag your question with Linux? Commented Jan 7, 2012 at 16:14

2 Answers 2

1
$FILES=`find /release/ext -name *stores*.dat`
for FILE in $FILES do
  # need to test for empty, case $FILES is empty
  test -n "$FILE" && /do/whatever/you/want
done;
Sign up to request clarification or add additional context in comments.

7 Comments

He said he didn't want the search to be recursive. This snippet will break on files with spaces. I don't know if SunOS 5.10 find supports -maxdepth.
@jordanm OQ examples show no spaces. If subdirectories exist (not in OQ) you can use something like test -n "$FILE" && test `dirname "$FILE"` == "/release/ext" && /do/what/you/want if you don't have maxdepth
There is no need to handle spaces in filenames. But does there have to be a separate loop for 'stores','hr'.etc? And can the other arguments stay next to the filename?
You can use $ALLFILES="*stores*.dat hr*.dat *emp*.txt"; for FILES in $ALLFILES ... . Arguments are meant to be part of /do/whatever/you/want
You don't need a subshell to get dirname. "${FILE%/*}" will give you the same result as dirname. Also you can use the bash keyword [[ instead of test, which will imply -n. [[ $FILE ]] && ...
|
1

It is unclear what the pipe characters and numbers are for in your $FILES variable. However, here is something you might find useful:

#!/bin/bash
filespecs='*stores*.dat *hr*.dat *emp*.txt'
dir='/release/ext'

cd "$dir"
for file in $filespecs
do
    sh myexternalscript.sh "$dir/$file"
done

Note that your question is tagged "bash" and you use "bash" in your shebang, but for some reason, you use "sh" when you call your other script. On some systems, sh is symlinked to Bash, but it will behave differently than Bash when called directly. On many systems, sh is completely separate from Bash.

In order to expand the globs and incorporate other arguments, you will need to violate the Bash rule of always quoting variables (this is an example of one of the exceptions).

filespecs='*stores*.dat | 3
*hr*.dat 4 5
*emp*.txt 6 7 8'
while read -r spec arg1 arg2 arg3 arg4
do
    sh myexternalscript.sh "$dir"/$spec "$arg1" "$arg2" "$arg3" "$arg4"
done < <(echo "$filespecs")

Use as many "arg" arguments as you think you'll need. Extras will be passed as empty, but set arguments. If there are more arguments than variables to accept them, then the last variable will contain all the remainders in addition to the one that corresponds to it. This version doesn't need the cd since the glob isn't expanded until the directory has been prepended, while in the first version the glob is expanded before the directory is prepended.

If you quote the pipes in the manner shown in your question, then the double quotes will be included in the argument. In the way I show it, only the pipe character gets passed but it's protected since the variable is quoted at the time it's referenced.

2 Comments

the pipe characters and numbers in the $FILES variable are arguments accepted by the myexternalscript.sh script as it does not just take the filename as an argument. I tried your script but it did not work and just passed the literal <asterix>stores<asterix>.dat as an argument.
@toop: I omitted a cd command which was necessary in order to make it work. I added that, plus I added another version that should allow you to include your arguments. I'm certain there's a better way to do this, but I would need to see how your arguments are being derived for the "outer" script (if they're not hard-coded) and probably need to see how they're being consumed in the "inner" script.

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.