I have a script (myscript.sh) loop that greps some strings in many different files, stores them in a new file, and then cats the content of this file to the terminal:

for i in {1..201..5}; do
        grep "Pitch" filename-$i.log | cut -d" " -f25
done > pitch.txt
echo "========Pitch==========="
cat pitch.txt

Here's what I'd like to do instead from the command line:

./myscript.sh filename-$i.log

This then runs myscript.sh, looping over the variable i that I refer to in the argument to myscript.sh.

I hope I have explained my goal here properly!


If you want to pass the base part of thew different filenames as the first parameter to your script, change the loop to:

for i in {1..201..5}; do
        grep "Pitch" "${1}-${i}" | cut -d" " -f25
done > pitch.txt

(assuming the dash is always there, and not passed as part of the parameter, and the variable part of the filenames is always at the end)

  • The variable part is actually not at the end, but just before the file extension. Like this: filename-1.log. I updated the question to make it clearer what I want. – Yoda Mar 22 '17 at 9:43

It's not exactly clear what you are after, but from what I get is that you have 6 directories but each directory has files named in a similar fashion of having numbers at their end. Then you could do this like this:

for arg
   for i in {1..201..5}; do
      grep "Pitch" "$arg-$i" | cut -d" " -f25
   done > $arg/pitch.txt
   echo "========Pitch==========="
   cat $arg/pitch.txt

Use this syntax:

for ((i=0; i<=$1; i=(($i + 5)) ))
        grep "Pitch" filename-$i | cut -d" " -f25
done > pitch.txt
echo "========Pitch==========="
cat pitch.txt
  • for (( i=0; i<=$1; i+=5 ))... But it doesn't answer the question. – Kusalananda Mar 21 '17 at 12:23

This bash function should work:

foo() {
    shift 1
    echo "========${searchstring}===========" ; 
    grep --no-filename "${searchstring}" "$@" | \
    cut -d" " -f25 | tee "${searchstring,,}".txt 

Invoke like so:

foo Pitch filename-{1..201..5}

How it works. Since grep allows multiple file names from the command line, and bash allows prefixing a string to code like {1..10}, there's no need to pass file names one a time through a for loop. The cat and > can both be replaced by a single tee.

The first argument of foo is the search string, (e.g. "Match"), which the shell sets to "$1" -- that gets moved to a temporary variable $searchstring, then "Match" is removed with shift 1, so that "$@" contains only the filenames.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.