2

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:

#!/bin/bash                                                                                                                                                                                                                           
frequ=$1                                                                                                                                                                                                                    
tim=$2                                                                                                                                                                                                                        
zap=$3

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

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

#!/bin/bash

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

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" 
done

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"
done

Testing

I created six files:

$ ls -1
1.F
1.T
1.zap
2.F
2.T
2.zap

Output

# 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"
| improve this answer | |
  • 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")? – abubakr yagob Oct 16 '17 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 '17 at 9:12
  • Yeah, I got it. yes, I need to remove the quotations based on my desired result. – abubakr yagob Oct 16 '17 at 13:09
0

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
| improve this answer | |
  • 1
    Shouldn't use ls mywiki.wooledge.org/ParsingLs – jesse_b Oct 15 '17 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 ) – Sergiy Kolodyazhnyy Oct 15 '17 at 18:29
  • @Ed Neville Thank you for the quick response, I hear what you say I'll try it just in a minute. – abubakr yagob Oct 15 '17 at 18:34
  • It is still performing the whole commands on the first argument files(*.frequ) without the other two args. – abubakr yagob Oct 15 '17 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.