我在bash中有一个小脚本,它通过gnuplot生成图形.
一切正常,直到输入文件的名称包含空格.
一切正常,直到输入文件的名称包含空格.
这是我得到的:
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
解决方法
快速回答是你无法完全按照自己的意愿去做. Gnuplot在一个迭代中将字符串拆分为空格,并且没有办法(AFIK).根据您的需要,可能会有“解决方法”.你可以在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):],R) : S
奖励指向任何能够在没有递归的情况下弄清楚如何做到这一点的人……
然后你的(bash)循环看起来像:
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)) ? \ replace( S[:strstrt(S,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