Macos 从GAWK和Bash脚本调用Gnuplot,只打印第一个打印

Macos 从GAWK和Bash脚本调用Gnuplot,只打印第一个打印,macos,bash,gnuplot,gawk,Macos,Bash,Gnuplot,Gawk,好吧,就这么定了。我正在开始我的计算材料科学的本科论文,我正试图把一些脚本放在一起,帮助准备数据分析 我一直在准备一个GAWK脚本,它基本上会获取一些数据(安排在4列中),并捕获其中两个数据,然后在GNUPLOT中绘制它们。为了达到这个目的,我读入了包含多个时间步及其相关数据的数据文件,将该文件拆分为每个时间步的单独.dat文件 从那里,我只为GNUPLOT生成一个基本的输入脚本,并在数据文件中绘制每个时间步 问题在于,出于某种原因,生成的所有绘图都是完全相同的绘图(在本例中始终是第一个时间步)

好吧,就这么定了。我正在开始我的计算材料科学的本科论文,我正试图把一些脚本放在一起,帮助准备数据分析

我一直在准备一个GAWK脚本,它基本上会获取一些数据(安排在4列中),并捕获其中两个数据,然后在GNUPLOT中绘制它们。为了达到这个目的,我读入了包含多个时间步及其相关数据的数据文件,将该文件拆分为每个时间步的单独.dat文件

从那里,我只为GNUPLOT生成一个基本的输入脚本,并在数据文件中绘制每个时间步

问题在于,出于某种原因,生成的所有绘图都是完全相同的绘图(在本例中始终是第一个时间步),但它们保存为正确的时间步


我已经检查并跟踪了整个脚本中的每个变量/文件名,最后确定问题在于从脚本调用GNUPLOT。我拿出我的系统命令,编写了一个简短的bash脚本,从for循环调用gnuplot:

#!/bin/bash
for file in ./*gnu
do
   gnuplot $file
done
这仍然会引起同样的问题,所有的情节都是一样的。然后,我在包含.gnu文件的目录中的命令行中运行了gnuplot*gnu命令,它成功了

我想我只是想知道是否有一些缓冲区,我需要冲洗或如果我只是错过了什么

下面给出了GAWK脚本。我还是个新手,所以如果你想用一些建设性的批评来评论剧本,我也会非常感激

#!/opt/local/bin/gawk -v inputf=$1 -f                                                   

# Write gnuplot files and plot RDF data                                                 
function plot_rdf(timestep, Load_RDF_dat)
{
# Set number of digits in filenames to 6 so data is organized                           
    if (timestep < 10){
        pad_timestep="00000"timestep;
    }
    else if (timestep < 100){
        pad_timestep="0000"timestep;
    }
    else if (timestep < 1000){
        pad_timestep="000"timestep;
    }
    else if (timestep < 10000){
        pad_timestep="00"timestep;
    }
    else if (timestep < 100000){
        pad_timestep="0"timestep;
    }
    else{
        pad_timestep=timestep;
    }

# Give output filenames                                                                 
       gnu_file="plot_RDF_"pad_timestep".gnu";
       png_file="RDF_"pad_timestep".png";

# Create input files for gnuplot                                                        
       print "set output \""png_file"\"" >> gnu_file;
       print "set terminal png" >> gnu_file;
       print "plot './"Load_RDF_dat"' u 1:2" >> gnu_file;
       close(gnu_file);
       system("gnuplot "gnu_file);
}


# Main part of script                                                                   
{
# Parse the RDF data and save it to GNUPLOT readable files                              
    while(getline < inputf){
       if ($1 == "#"){
           # skips the three commented header lines                                     
           next;
       }
       else if (NF == 2){
           timestep=$1;
           bin_num=$2;
           print "Reading timestep "timestep;
           RDF_dat="RDF_"timestep".dat";
           next;
       }
       else if (NF == 4){
           print $2" "$3 >> RDF_dat;
           if ($1 == bin_num){
               plot_rdf(timestep, RDF_dat);
               close(RDF_dat);
           }
           next;
       }
    }
    close(inputf);
    close(RDF_dat);
 }

通常每个时间步部分都有100组数据,但我想我会在这里缩短,以便让您了解情况。

我不确定我是否能回答您的问题——但是,我要说的是,当我稍微修改您的数据文件时,它(似乎)对我来说效果很好

以下是我对您的数据文件的修改版本:

# Time-averaged data for fix rdf
# TimeStep Number-of-rows
# Row c_allrdf[1] c_allrdf[2] c_allrdf[3]
500 100
1 0.005 0 0
2 0.015 0 0
3 0.025 0 0
4 0.035 0 0
5 0.045 0 0
6 0.055 1.16597 0.00133333
7 0.065 2.08865 0.00466667
8 0.075 1.56958 0.008
9 0.085 0.733433 0.01
10 0.095 0.587288 0.012
100 0.095 0.56 0.014     #<-added this line
600 100
1 0.005 0 0
2 0.015 0 0
3 0.025 2.79219 0.000666667
4 0.035 2.86766 0.002
5 0.045 0 0.002
6 0.055 0.582985 0.00266667
7 0.065 2.08865 0.006
8 0.075 0.62783 0.00733333
9 0.085 0.488955 0.00866667
10 0.095 1.17458 0.0126667
100 0.095 1.179 0.12      #<-added this line
因为
bin_num
取自“header”中的第二个字段。(例如,
600 100

我不确定您是否在完整的数据文件中正确设置了它。此外,我将脚本称为:

gawk -f test.awk -v inputf=test.dat test.dat
这完全忽略了一开始的shebang,但是我已经读到很多系统在正确地分解它们时有困难


最后,您有什么版本的gnuplot?如果你有4.6,你可以放弃很多痛苦,完全跳过
gawk
脚本,用一个更简单的脚本替换它。

我不确定我是否能回答你的问题——但是,我要说的是,当我稍微修改你的数据文件时,它(似乎)对我来说很好

以下是我对您的数据文件的修改版本:

# Time-averaged data for fix rdf
# TimeStep Number-of-rows
# Row c_allrdf[1] c_allrdf[2] c_allrdf[3]
500 100
1 0.005 0 0
2 0.015 0 0
3 0.025 0 0
4 0.035 0 0
5 0.045 0 0
6 0.055 1.16597 0.00133333
7 0.065 2.08865 0.00466667
8 0.075 1.56958 0.008
9 0.085 0.733433 0.01
10 0.095 0.587288 0.012
100 0.095 0.56 0.014     #<-added this line
600 100
1 0.005 0 0
2 0.015 0 0
3 0.025 2.79219 0.000666667
4 0.035 2.86766 0.002
5 0.045 0 0.002
6 0.055 0.582985 0.00266667
7 0.065 2.08865 0.006
8 0.075 0.62783 0.00733333
9 0.085 0.488955 0.00866667
10 0.095 1.17458 0.0126667
100 0.095 1.179 0.12      #<-added this line
因为
bin_num
取自“header”中的第二个字段。(例如,
600 100

我不确定您是否在完整的数据文件中正确设置了它。此外,我将脚本称为:

gawk -f test.awk -v inputf=test.dat test.dat
这完全忽略了一开始的shebang,但是我已经读到很多系统在正确地分解它们时有困难


最后,您有什么版本的gnuplot?如果你有4.6,你可以放弃很多痛苦,完全跳过
gawk
脚本,代之以一个更简单的脚本。

正如mgilson所指出的,你可能因为没有
$1==bin\u num
而无法调用plot\u rdf。请注意,在命令行上使用数据文件名调用awk可以方便地使用awk的内置文件读取循环。下面的awk程序重写说明了这一点。另请注意:
•在两个位置使用
而不是
>

•在运行gnuplot之前而不是之后关闭RDF_dat
•使用
pad\u timestep=sprintf(“%06d”,timestep)而不是一系列笨拙的
if
语句

对于以下内容,我将程序放入文件
so gnuplot awk
,数据原样放入文件
data so gnuplot
,并通过

awk -f so-gnuplot-awk data-so-gnuplot
节目:

# Parse the RDF data and save it to GNUPLOT readable files
BEGIN { dopen=0 }

NF==2 {
    if (dopen) plot_rdf(timestep, RDF_dat);
    timestep = $1;
    print "Reading timestep "timestep;
    RDF_dat="RDF_"timestep".dat";
    printf "" > RDF_dat     # Init empty file
    dopen = 1;
}

NF == 4 {  if (dopen) print $2" "$3 >> RDF_dat; }

# Write gnuplot files and plot RDF data
function plot_rdf(timestep, Load_RDF_dat) {
# Set output filenames & create gnuplot command file
    pad_timestep = sprintf("%06d", timestep);
    gnu_file="plot_RDF_"pad_timestep".gnu";
    png_file="RDF_"pad_timestep".png";
    print "set output \""png_file"\"" > gnu_file; # Use > first
    print "set terminal png" >> gnu_file;
    print "plot './"Load_RDF_dat"' u 1:2" >> gnu_file;
    close(gnu_file);
    close(RDF_dat);
    print "Plotting with "RDF_dat" into "png_file
    system("gnuplot "gnu_file);
    dopen=0
}

END { if (dopen) plot_rdf(timestep, RDF_dat); }

正如mgilson所指出的,您可能因为没有
$1==bin_num
而未能调用plot_rdf。请注意,在命令行上使用数据文件名调用awk可以方便地使用awk的内置文件读取循环。下面的awk程序重写说明了这一点。另请注意:
•在两个位置使用
而不是
>

•在运行gnuplot之前而不是之后关闭RDF_dat
•使用
pad\u timestep=sprintf(“%06d”,timestep)而不是一系列笨拙的
if
语句

对于以下内容,我将程序放入文件
so gnuplot awk
,数据原样放入文件
data so gnuplot
,并通过

awk -f so-gnuplot-awk data-so-gnuplot
节目:

# Parse the RDF data and save it to GNUPLOT readable files
BEGIN { dopen=0 }

NF==2 {
    if (dopen) plot_rdf(timestep, RDF_dat);
    timestep = $1;
    print "Reading timestep "timestep;
    RDF_dat="RDF_"timestep".dat";
    printf "" > RDF_dat     # Init empty file
    dopen = 1;
}

NF == 4 {  if (dopen) print $2" "$3 >> RDF_dat; }

# Write gnuplot files and plot RDF data
function plot_rdf(timestep, Load_RDF_dat) {
# Set output filenames & create gnuplot command file
    pad_timestep = sprintf("%06d", timestep);
    gnu_file="plot_RDF_"pad_timestep".gnu";
    png_file="RDF_"pad_timestep".png";
    print "set output \""png_file"\"" > gnu_file; # Use > first
    print "set terminal png" >> gnu_file;
    print "plot './"Load_RDF_dat"' u 1:2" >> gnu_file;
    close(gnu_file);
    close(RDF_dat);
    print "Plotting with "RDF_dat" into "png_file
    system("gnuplot "gnu_file);
    dopen=0
}

END { if (dopen) plot_rdf(timestep, RDF_dat); }

“最终确定问题出在某种程度上是GNUPLOT被脚本调用了”-你不觉得这个结论有多奇怪吗?问题出在你的脚本中,不是从脚本调用gnuplot。“最后确定问题出在某种程度上是从脚本调用gnuplot”——你不觉得这个结论有多奇怪吗?问题出在您的脚本中,没有从脚本调用gnuplot。是的,我很抱歉,您是对的,它确实需要匹配数据中的bin编号才能触发下一个文件。当我发布样本数据时,我没有考虑到这一点。我正在使用Gnuplot 4.6,但我不知道您可以在Gnuplot中执行此操作。是的,对此我很抱歉,您是对的,它确实需要匹配数据中的bin号才能触发下一个文件。当我发布样本数据时,我没有考虑到这一点。我正在使用Gnuplot 4.6,但我不知道你可以在Gnuplot中实现这一点。看到别人写呆板的脚本肯定有助于我更好地理解这门语言。谢谢你的帮助!啊,谢谢你,这对我有用。看到别人写g