Извините за непонятное название. Я не мог найти лучшего названия, чтобы описать проблему. Я использую gnuplot для печати некоторых файлов. Файлы, которые я пытаюсь построить, находятся в папке с названием process. Внутри папки процесса находится еще одна папка с именем 100; структура как показано ниже;

"plot" - это файл, который я вспоминаю с помощью gnuplot.

Сюжет файла имеет следующую строку;

file='file.dat'
time = "cat file | grep 'time' | cut -d' ' -f2 | tr -d ';' | awk 'NR==1{print $1}'"

plot \
      "process/".time."/speed.txt" using 1:3 with line lt 2 lc 6 title ""

Итак, цель состоит в том, чтобы найти слово time в файле file.dat и сократить его значение, которое в данном случае равно 100, и использовать его в качестве имени папки, в которой я пытаюсь построить файл speed.txt. Однако то, что у меня есть, похоже, не работает, когда я выполняю gnuplot. Кто-нибудь может помочь?

Большое спасибо!

1
Programming 7 Окт 2020 в 05:46

2 ответа

Лучший ответ

Прежде всего, чтобы запустить команду оболочки из gnuplot и получить ее стандартный вывод в виде текста, используйте функцию system.

filter_command = "cat ..." 
time = system( filter_command )

Во-вторых, указанная вами командная строка "cat ..." не будет работать должным образом, если вы просто передадите ее system. Вы хотите, чтобы строка file в cat file была расширена как cat file.dat из переменной gnuplot file. Для этого нам нужен еще один шаг. Это можно сделать двумя способами.

  1. Объединение строк с помощью оператора .
file='file.dat'
filter_command = "cat " . file . " | grep 'time' | cut -d' ' -f2 | tr -d ';' | awk 'NR==1{print $1}'" 
  1. Использование функции sprintf
file='file.dat'
filter_template = "cat %s | grep 'time' | cut -d' ' -f2 | tr -d ';' | awk 'NR==1{print $1}'" 
filter_command  = sprintf(filter_template, file)

Сценарий

Окончательный сценарий выглядит так.

file='file.dat'
filter_template = "cat %s | grep 'time' | cut -d' ' -f2 | tr -d ';' | awk 'NR==1{print $1}'" 
filter_command  = sprintf(filter_template, file)

time = system( filter_command )

plot "process/".time."/speed.txt" using 1:3 with line lt 2 lc 6 title ""
1
binzo 7 Окт 2020 в 23:25

Хотя gnuplot не предназначен для анализа файлов, вы, тем не менее, можете это сделать, иногда со странными обходными путями. Конечно, есть способ сделать это с помощью упомянутых вами инструментов: cat, grep, cut, tr и awk. Однако не все используют Linux и имеют под рукой эти инструменты. Следовательно, если возможно и хотя это не оптимально, я лично предпочитаю иметь решения «только для gnuplot», которые не зависят от платформы.

Итак, то, что в основном делает приведенный ниже код, состоит в том, чтобы «построить» файл file.dat в фиктивной таблице построчно и каждый раз проверять, содержит ли текущая строка строку time:. Если да, впишите оставшуюся часть строки в переменную myValue.

Получите дополнительную информацию о командах: help strstrt, help strlen, help strcol, help ternary, help datafile separator.

Файл: file.dat

### file.dat
This is a data file
which contains something
but also a line with
time:100
And many more things...
Maybe also some data...?
1  1.1
2  2.2
3  3.3
4  4.4
# end of file

Код:

### extract key&value from a file and use it in path
reset session

myFile = 'file.dat'
myKey = 'time:'
myValue = ''
myPath(s) = sprintf('process/%s/speed.txt',s)
getValue(line) = strstrt(line,myKey) > 0 ? myValue = line[strstrt(line,myKey)+strlen(myKey):] : myValue

# extract the value for key
set datafile separator "\n"
set table $Dummy
    plot myFile u (getValue(strcol(1))) w table
unset table
set datafile separator whitespace

print myValue
print myPath(myValue)

# Your plot command would then look, e.g. like this:
plot myPath(myValue) using 1:3 with line lt 2 lc 6 title ""

### end of code

Результат:

100
process/100/speed.txt
1
theozh 7 Окт 2020 в 19:42