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

Moh*_*awy 2 scripting sed text-processing

我有 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
Run Code Online (Sandbox Code Playgroud)

但这无济于事

这应该在exe脚本中进行更改

set term png size 1600,1200
set output "X_001.png"
splot 'X_001'
Run Code Online (Sandbox Code Playgroud)

Nom*_*mal 7

我更喜欢使用 Bash 脚本和 here-document 来包含直接提供给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
Run Code Online (Sandbox Code Playgroud)

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用于启动此文件中的Bash。内容,最多(但不包括)以 开头的行,END-MARKER作为输入提供。但是,变量扩展是在本文中完成的,因此您可以使用here 文档中的$variableor${variable}语法(和其他语法),它们将被替换为它们的内容。

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