Search code examples
bashksh

execute a shell script against a list of arguments from the terminal


occasionally, but not often enough to need to write a script for it, i may need to run 'foo' against a set of arguments. It may vary which argument is static vs which is a list, and it may vary the length of the list.

to illustrate what i am trying to do, please consider

rm ./$(ls -lrt foo | awk '{print $9}')

as a demonstration of the same functionality i am trying to achieve (excepting of course this syntax rm is interactive, the script in question would not be, but rm performs action against the set of args given to it) instead of, eg

foo 1 2a 3; foo 1 2b 3; foo 1 2c 3

is there some syntax from the terminal (this system has access to either ksh88 or bash) that I could for instance

foo 1 $(2a,2b,2c) 3

or similar, such that i could enter once the script and constant args and automate only the part that is needed in the moment? the args needed may or may not be sequential or otherwise a pattern that would make sense to use a for loop. So i would be listing, whether csv or some other kind of way each one explicitly without being able to provide it via the output of any other command.

I am sure any shell is capable of doing what i intend i just don't have a way to test what might work outside of production.

thanks in advance.

edit: to 2a-2c may not have illustrated as precisely, the arg could have been (apple,banana,orange) ie they are not necessarily 2(a..c) in such simple terms.


Solution

  • A simple shell loop:

    for arg in apple banana orange; do
        foo 1 "$arg" 3
    done
    

    or a while-read loop:

    some_process_that_generates_arguments | while IFS= read -r line; do
        foo 1 "$line" 3
    done
    
    # usually better to write that like this:
    while IFS= read -r line; do
        foo 1 "$line" 3
    done < <(some_process_that_generates_arguments)
    

    Or with xargs

    some_process_that_generates_arguments | xargs -I ARG foo 1 ARG 3
    

    demo

    $ seq 5 8 | xargs -I ARG echo first ARG last
    first 5 last
    first 6 last
    first 7 last
    first 8 last
    

    In your question, using ls indicates you want to do stuff with files. ls is the wrong tool for that: you should either use shell globs or find.

    Assuming you want to find all files under directory "foo":

    shopt -s globstar nullglob
    for path in foo/**; do
        [[ -f $path ]] || continue
        do_something_with "$path"
    done
    

    or

    find foo -type f -exec do_something_with '{}' \;