我正在文件的同一目录中工作。我有具有三个不同扩展名的文件。我想通过将它们作为参数传递给 for 循环来对具有特定扩展名的文件执行五个命令中的每一个。
示例:我希望当我运行如下代码时:$my_code.sh *.zap *.F *.T
我希望脚本执行特定扩展中的每个命令,并在末尾准备一个命令列表并将它们附加为输出。
当我按原样运行代码时,它只会采用第一个参数(其中包含带有 *.zap 文件的文件)并执行其上的所有命令,但我想要的是将每个命令应用到具有扩展名的特定文件中。
这是我的代码:
#!/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
答案1
在您的情况下,将所有命令放入单个for
循环中是没有意义的。您没有针对所有文件的通用操作 - 每个扩展都有自己的命令,并且它们不相交。因此,您将需要使用if
或switch
来区分一个扩展与另一个扩展。为什么要这样做呢?为每个扩展创建自定义循环会更容易。
我决定不将扩展传递给脚本,而是直接将它们写入代码中。另外,我选择printf
- 它更适合这项任务。
用法: ./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
测试
我创建了六个文件:
$ ls -1
1.F
1.T
1.zap
2.F
2.T
2.zap
输出
# 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"
答案2
我认为可以做得更好的一种方法是,如果您将输入仅作为扩展名发送,而不是与扩展名匹配的文件。问题是您的脚本否则必须清除哪些文件属于哪个组。然后,循环可能会变得不那么复杂,因为您可以使用内部扩展进行全局扩展。
您当前拥有的循环作为 while read 循环会更好地工作,如下所示:
ls -1 * | while read i; do ... done >> ps_files.txt
或者作为 for,像这样:
for i in `ls -1 *`; do ... done >> ps_files.txt