2012-06-19 2 views
4

У меня есть небольшой скрипт в bash, который генерирует графики через gnuplot. Все работает нормально, пока имена входных файлов не содержат пробелов.gnuplot для цикла и пробелов в filename

Вот что я получил:

INPUTFILES=("data1.txt" "data2 with spaces.txt" "data3.txt") 

... 

#MAXROWS is set earlier, not relevant. 


for LINE in $(seq 0 $((MAXROWS - 1)));do 

gnuplot << EOF 
reset 
set terminal png 
set output "out/graf_${LINE}.png" 

filenames="${INPUTFILES[@]}" 

set multiplot 

plot for [file in filenames] file every ::0::${LINE} using 1:2 with line title "graf_${LINE}" 

unset multiplot 
EOF 
done 

Этот код работает, но только без пробелов в именах входных файлов.

В примере GNUPLOT оценить это:

1 iteration: file=data1.txt - CORRECT 
2 iteration: file=data2 - INCORRECT 
3 iteration: file=with - INCORRECT 
4 iteration: file=spaces.txt - INCORRECT 
+1

Не используйте 'seq'. 'for ((line = 0; line ormaaj

+0

@ormaaj исправленный вопрос. Я имел в виду некоторые системные вызовы из gnuplot .. как sed для переключения пробелов в тире, а затем обратно. И почему бы не использовать имена переменных seq (readability?!) И all-caps? – Rob

ответ

1

быстрый ответ в том, что вы не можете делать то, что вы хотите сделать. Gnuplot разбивает строку на итерации на пространствах, и нет никакого способа обойти это (AFIK). В зависимости от того, что вы хотите, может быть «Work-around». Вы можете написать функцию (рекурсивно) в Gnuplot заменить строку символов с другой -

#S,C & R stand for STRING, CHARS and REPLACEMENT to help this be a little more legible. 
replace(S,C,R)=(strstrt(S,C)) ? \ 
    replace(S[:strstrt(S,C)-1].R.S[strstrt(S,C)+strlen(C):] ,C,R) : S 

бонусные баллы для тех, кто может понять, как сделать это без рекурсии ...

Тогда ваш (Баш) цикл выглядит примерно так:

INPUTFILES_BEFORE=("data1.txt" "data2 with spaces.txt" "data3.txt") 
INPUTFILES=() 
#C style loop to avoid changing IFS -- Sorry SO doesn't like the #... 
#This loop pre-processes files and changes spaces to '#_#' 
for ((i=0; i < ${#INPUTFILES_BEFORE[@]}; i++)); do 
    FILE=${INPUTFILES_BEFORE[${i}]} 
    INPUTFILES+=("`echo ${FILE} | sed -e 's/ /#_#/g'`") #replace ' ' with '#_#' 
done 

, который выполняет предварительную обработку входных файлов для добавления «# _ #» в именах файлов, имеющих пробелы в них ... И, наконец, «полный» сценарий:

... 

INPUTFILES_BEFORE=("data1.txt" "data2 with spaces.txt" "data3.txt") 
INPUTFILES=() 
for ((i=0; i < ${#INPUTFILES_BEFORE[@]}; i++)); do 
    FILE=${INPUTFILES_BEFORE[${i}]} 
    INPUTFILES+=("`echo ${FILE} | sed -e 's/ /#_#/g'`") #replace ' ' with '#_#' 
done 

for LINE in $(seq 0 $((MAXROWS - 1)));do 
gnuplot <<EOF 
filenames="${INPUTFILES[@]}" 
replace(S,C,R)=(strstrt(S,C)) ? \ 
     replace(S[:strstrt(S,C)-1].R.S[strstrt(S,C)+strlen(C):] , C ,R) : S 
#replace '#_#' with ' ' in filenames. 
plot for [file in filenames] replace(file,'#_#',' ') every ::0::${LINE} using 1:2 with line title "graf_${LINE}" 

EOF 
done 

Однако, я думаю, что отводящий здесь является то, что вы не должны использовать пробелы в именах файлов;)

+0

Да, вот и все. Я почти сделал немыслимое и реализованное решение с tmp-файлами (копии оригиналов, но имена без пробелов) :) Спасибо! – Rob

+1

@ Rob - Хороший улов на редактирование. Этот был для меня довольно интересным вызовом. благодаря – mgilson

0

Побег пространства:

"data2\ with\ spaces.txt" 

EDIT

Кажется, что даже с экранирующие последовательности, как вы упоминали, bash for всегда будет анализировать входные данные в пробелах.

Вы можете преобразовать ваш сценарий работать в моде в while петли:

http://ubuntuforums.org/showthread.php?t=83424

Это также может быть решением, но это ново для меня, и я до сих пор играет с ним, чтобы понять, что именно это делает:

http://www.cyberciti.biz/tips/handling-filenames-with-spaces-in-bash.html

+0

Это не поможет. Как вы можете видеть, мои ВХОДНЫЕ ФАЙЛЫ находятся в "" – Rob

+0

Проблема возникает в оценке gnuplot "for cycle".Gnuplot вообще не заботится о "". – Rob

+0

Я знаком с переменной bash IFS **, но ** эта проблема касается «** gnuplot ** для оценки цикла». – Rob

Смежные вопросы