I'm working in the same directory of the files. I have files with three different extensions. I want to perform each one of the five commands on a file with the specific extension by passing them as arguments to the for loop.

example: I want when I run the code like: $my_code.sh *.zap *.F *.T
I want the script to perform each command in the specific extension and prepare a list of command at the end and append them as output.

When I run the code as is, it will just take the first arguments (which contains files with *.zap files) and will perform all the commands on it, but what I want is apply each command in specific files with extension.

here is my code:


ls -1 * |                                                                                                                                                                                                                     
for i in "$@"; do                                                                                                                                                                                                       
        echo pav -g \""$frequ"_"avprof.ps/cps"\" -DT $frequ                                                                                                                                                     
        echo pav -g \""$tim"_"fprof.ps/cps"\" -Gd $tim                                                                                                                                                            
        echo pav -g \""$tim"_"ds.ps/cps"\" -j $tim                                                                                                                                                            
        echo pav -g \""$frequ"_"stack.ps/cps"\" -R $frequ                                                                                                                                                                   
        echo psrplot -D \""$zap"_"bp.ps/cps"\" -p  freq+ $zap                                                                                                                                                                              
done >> ps_files.txt 

2 Answers 2


It makes no sense put all commands into the single for loop, in your case. You don't have common actions for all files - each extension has own commands and them doesn't intersects. Thus, you will need use if or switch for distinguishing one extension from another. Why do so? It will be easier to create a custom loop for each extension.

I decided don't pass extensions to the script, but write them into code directly. Also, I picked printf - it is more suitable for this task.

Usage: ./my_script.sh > ps_files.txt


for i in *.zap; do
    printf 'psrplot -D "%s_bp.ps/cps" -p  freq+ "%s"\n' "$i" "$i"

for i in *.T; do
    printf 'pav -g "%s_fprof.ps/cps" -Gd "%s"\n' "$i" "$i" 
    printf 'pav -g "%s_ds.ps/cps" -j "%s"\n' "$i" "$i" 

for i in *.F; do
    printf 'pav -g "%s_avprof.ps/cps" -DT "%s"\n' "$i" "$i"
    printf 'pav -g "%s_stack.ps/cps" -R "%s"\n' "$i" "$i"


I created six files:

$ ls -1


# run my script
$ ./my_script.sh > ps_files.txt

# and look at the ps_files.txt content
$ cat ps_files.txt 

psrplot -D "1.zap_bp.ps/cps" -p  freq+ "1.zap"
psrplot -D "2.zap_bp.ps/cps" -p  freq+ "2.zap"
pav -g "1.T_fprof.ps/cps" -Gd "1.T"
pav -g "1.T_ds.ps/cps" -j "1.T"
pav -g "2.T_fprof.ps/cps" -Gd "2.T"
pav -g "2.T_ds.ps/cps" -j "2.T"
pav -g "1.F_avprof.ps/cps" -DT "1.F"
pav -g "1.F_stack.ps/cps" -R "1.F"
pav -g "2.F_avprof.ps/cps" -DT "2.F"
pav -g "2.F_stack.ps/cps" -R "2.F"
  • I can't thank you enough : ) really you made my day. It works beautifully! now I just need to get rid of the quotation from the last part of the output "1.F" to be 1.zap without quotation in (e.g psrplot -D "1.zap_bp.ps/cps" -p freq+ "1.zap")? Oct 16, 2017 at 1:12
  • @abubakryagob Filename quotation is needed, else filenames with spaces will not processed correctly. For example: ls filename with space.txt is processed as three files by ls - filename, with, space.txt. But ls "filename with space.txt" command, have the one file - "filename with space.txt". However, if you want remove quotes anyway, it is easy - convert the "%s" part to the %s in the each printf command.
    – MiniMax
    Oct 16, 2017 at 9:12
  • Yeah, I got it. yes, I need to remove the quotations based on my desired result. Oct 16, 2017 at 13:09

One way I think that would make this better is if you send the input as just the extension, not the files that match the extension. The problem is that your script would otherwise have to weed out which files belong to which group. The loops then could become less complex as you can do the glob expansion with the extension inside.

The loop you currently have would work better as a while read loop, like so:

ls -1 * | while read i; do ... done >> ps_files.txt

or as a for, like so:

for i in `ls -1 *`; do ... done >> ps_files.txt
  • 1
    Shouldn't use ls mywiki.wooledge.org/ParsingLs
    – jesse_b
    Oct 15, 2017 at 18:23
  • Aside from parsing output of ls which is already a great sin, doing for i in 'ls -1 *' is redundant. Just use globbing for i in * There's no need to spawn separate ls process to deal with files in current working directory. If it's a recursive case then yes, you'll need find -print0 | while IFS= read -r -d '' structure, but that's whole lot of different story. Also, for the love of sysadmin's coffee, please don't use backticks to do command-substitution, use $(...) like command1 $( command2 arg1 arg2 ) Oct 15, 2017 at 18:29
  • @Ed Neville Thank you for the quick response, I hear what you say I'll try it just in a minute. Oct 15, 2017 at 18:34
  • It is still performing the whole commands on the first argument files(*.frequ) without the other two args. Oct 15, 2017 at 19:57

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.