0

Ok, so I have a bunch of test_xx and validate_xx files that I want to execute in the following way:

./path/test_01 | ./server | ./path/validate_01

./path/test_02 | ./server | ./path/validate_02

... And so on.

Now then, I want to create a run_all script that will locate all of these other scripts and run them all in this way.

I can use the following code to find and execute only, for example, test_01:

find ./*/ -name test_01 -exec {} \;

So, I have two problems:

  1. (Important!) How can I make bash execute the more complicated line above, with piping and two unknown directories to search for? I can only find how to execute a single command.

  2. (Less important, but still an issue...) What would be the best way to loop this script, so that it executes all test/validate scripts in the directory, then stops? The scripts are currently named test_01, test_02, ..., test_26 (and similarly for validate_xx) - but I want to script to still work, without changing, if I add test_27 etc.

1
  • Try this one: find . -name "test_*" | xargs -i sh -c '{} | ./server | echo {} | sed 's/test_/validate_/' ' Commented Jan 7, 2013 at 10:40

2 Answers 2

1

If they don't span multiple directories, you don't need to use find:

for test in path/test*; do $test | ./server | ${test/test/validate}; done

BTW, useful tidbit: ${a/b/c} syntax says: take value of variable a, and replace b with c.

If you do need find, then you can wrap redirection inside a shell script:

find dir -exec sh -c '... | ... | ...' \;

EDIT: in a bit more detail,

find . -name test\* -exec sh -c '
  test={}
  validate=${test/test/validate}
  $test | ./server | $validate
' \;
Sign up to request clarification or add additional context in comments.

5 Comments

Tests are stored in different folders, so I do need to use find -- sorry, I should have been clearer there. (However, each test_xx script is in the same folder as its corresponding validation_xx script -- so it's probably possible to use some shortcut here) The relevant bit of code now looks like this: (starting with i="1") find ./*/ -name test_0$i -exec sh -c '{} | ./server' ...Which works, so it seems I'm on the right track. But how to incorporate validate_01? Hmm...
@TomLord: Okay, I believe this should do the trick. No need for an explicit loop, find itself is all the loop you need.
Thank you!! The "EDIT" you added above works perfectly, and without the need for any indexing variables like I was attempting. I'll come back and upvote your response once I've been on this site long enough for it to allow me to, haha!
Your use of find is broken here if any files contain whitespace or embedded semicolons. Also, the invocation is broken if the script exists in a directory with spaces. It should be: find . -name 'test*' -exec sh -c '"$1" | ./server | "${1/test/validate}"' _ {} ';'
@JoshCartwright: In general case, yes. I was trusting the OP that his files were test_## and validate_##, which do not necessitate quotage. I guess that part of the answer was tailor-made for the question.
0

Use a for loop. For example, you can loop over the tests and extract the number from them via Parameter expansion:

for test in ./path/test_[0-9][0-9] ; do
    "$test" | ./server | ./path/validate_${test: -2}
done

Comments

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.