如何在多个文件上循环脚本?

如何在多个文件上循环脚本?

我有 Gnuplot 脚本(EXE文件),在我提供的这个脚本中X_001作为由某个函数绘制的输入文件,给出输出文件X_001.png。如果我手动输入输入和输出文件的名称,效果很好。我试图在文件上循环这个脚本{X_001..X_300} 我写了这个循环

for i in X_*; do sed -i 's/X_*/${i}/g' exe ; ./exe ; done

但这没有帮助

这是变化的地方EXE文件应该制作脚本

set term png size 1600,1200
set output "X_001.png"
splot 'X_001'

答案1

我更喜欢使用 Bash 脚本和此处文档来包含直接提供给gnuplot.您不想真正用于X_*输入和X_*.png输出,因为前者包含后者 - 也就是说,如果您第二次运行循环而不删除 PNG 文件,您将尝试将它们用作数据。因此,假设我们的数据文件是X_*.out,并且我们希望将它们绘制为X_*.png

#!/bin/bash
export LANG=C LC_ALL=C

for data in X_*.out ; do
    [ -r "$data" ] || continue
    png="${data%.*}.png"

    gnuplot <<END-OF-PLOT

        set term png enhanced size 1024,512
        set output "$png"

        set title "$data"
        plot "$data" u 1:2 notitle w lines

END-OF-PLOT
done

export LANG=C LC_ALL=C行设置默认的 C/POSIX 语言环境。它只是确保如果其他人(比如您的讲师/老师/助教)执行相同的脚本,但碰巧使用不同的语言(并且更喜欢与您不同的语言环境),他们仍然会重新生成相同的绘图。

(问题是某些语言环境使用.作为小数点,其他语言环境使用,。我通过切换到始终可用的 C/POSIX 语言环境来避免这种歧义。并用作.小数点。)

如果没有与 glob 模式匹配的文件X_*.out,则默认情况下 Bash 会在循环体上迭代一次并data具有值X_*.out本身。该[ -r "$data" ] || continue测试检查变量中是否存在指定的可读文件data。如果不是,则跳到下一次迭代(循环体的其余部分不会针对该值执行)。

请注意png赋值:${data%.*}计算结果为变量的值data(此处为数据文件名),但从最后开始的所有内容都.将被删除。 (如果没有.in data,则不会删除任何内容。)

因此,在 Bash 中,${data%.*}.png计算结果为 的值data,但如果它具有文件名后缀,则将其替换为.png.如果它没有文件名后缀,.png则附加到它。

用于<<END-MARKER启动这里的文档在巴什中。最多(但不包括)以 开头的行的内容END-MARKER作为输入提供。但是,变量扩展是在本文中完成的,因此您可以在此处文档中使用$variableor${variable}语法(以及其他语法),它们将被替换为其内容。

请注意,与 Bash 命令行命令不同,Bash 此处文档中的引号会被保留。因此,如果png有 value X_001.out,则set output "$png"扩展为,并且 Gnuplot 将其视为set output "X_001.out"

答案2

制作模板脚本,例如exe-template.在模板脚本中使用占位符作为输入文件和输出文件的名称;例如,用于X_input输入文件和X_input.png输出文件。

set term png size 1600,1200
set output "X_input.png"
splot 'X_input'

然后,在循环中,使用sed替换X_input为数据文件的名称,并将生成的修改脚本写入临时文件,例如exe-tmp

for i in X_[0-9][0-9][0-9] ; do
  sed -e 's/X_input/'${i}'/g' exe-template >exe-tmp
  chmod 755 ./exe-tmp
  ./exe-tmp
done

相关内容