代码之家  ›  专栏  ›  技术社区  ›  Andrey Tyukin

“设置数据文件分隔符”| | |“`中的多字符分隔符无效。”

  •  1
  • Andrey Tyukin  · 技术社区  · 7 年前

    example.data 使用三重管道作为分隔符,日期在第一列中,最后一列中还有一些或多或少不可预测的文本:

    2019-02-01|||123|||345|||567|||Some unpredictable textual data with pipes|,
    2019-02-02|||234|||345|||456|||weird symbols @ and commas, and so on.
    2019-02-03|||345|||234|||123|||text text text
    

    当我尝试运行下面的gnuplot5脚本时

    set terminal png size 400,300
    set output 'myplot.png'
    
    set datafile separator "|||"
    set xdata time
    set timefmt "%Y-%m-%d"
    set format x "%y-%m-%d"
    plot "example.data" using 1:2 with linespoints
    

    line 8: warning: Skipping data file with no valid points
    
    plot "example.data" using 1:2 with linespoints
                                                  ^
    "time.gnuplot", line 8: x range is invalid
    

    更奇怪的是,如果我把最后一行改成

    plot "example.data" using 1:4 with linespoints
    

    然后它就起作用了。它也适用于 1:7 1:10 ,但不适用于其他数字。为什么?

    2 回复  |  直到 7 年前
        1
  •  1
  •   Andrey Tyukin    7 年前

    当使用

    set datafile separator "chars"
    

    语法,字符串是 作为一个长分离器处理。相反 每一个 引号之间列出的字符本身成为分隔符。自[Janert,2016]:

    如果提供显式字符串,则字符串中的每个字符都将 作为分隔符处理。

    set datafile separator "|||"
    

    实际上相当于

    set datafile separator "|"
    

    还有一条线

    2019-02-05|||123|||456|||789
    

    被视为有十列,其中只有列1、4、7、10是非空的。


    变通办法

    查找不太可能出现在数据集中的其他字符(我假设在下面的示例中) \t (例如)。如果无法使用其他分隔符转储数据集,请使用 sed 取代 ||| 通过 \t

    sed 's/|||/\t/g' example.data > modified.data # in the command line
    

    然后继续

    set datafile separator "\t"
    

    modified.data 作为输入。

        2
  •  1
  •   theozh    7 年前

    你基本上是自己给出答案的。

    1. 如果可以影响数据中的分隔符,请使用通常不会出现在数据或文本中的分隔符。我一直在想 \t

    2. 如果无法影响数据中的分隔符,请使用外部工具(awk、Python、Perl等)修改数据。在这些语言中,它可能是“一行”。gnuplot没有直接替换功能。

    编辑: https://stackoverflow.com/a/54541790/7295599 ).

    假设您的数据位于名为 $Data ||| \t 并将结果放入 $DataOutput

    ### Replace string in dataset
    reset session
    
    $Data <<EOD
    # data with special string separators
    2019-02-01|||123|||345|||567|||Some unpredictable textual data with pipes|,
    2019-02-02|||234|||345|||456|||weird symbols @ and commas, and so on.
    2019-02-03|||345|||234|||123|||text text text
    EOD
    
    # replace string function
    # prefix RS_ to avoid variable name conflicts
    replaceStr(s,s1,s2) = (RS_s='', RS_n=1, (sum[RS_i=1:strlen(s)] \
        ((s[RS_n:RS_n+strlen(s1)-1] eq s1 ? (RS_s=RS_s.s2, RS_n=RS_n+strlen(s1)) : \
        (RS_s=RS_s.s[RS_n:RS_n], RS_n=RS_n+1)), 0)), RS_s)
    
    set print $DataOutput
    do for [RS_j=1:|$Data|] {
        print replaceStr($Data[RS_j],"|||","\t")
    }
    set print
    
    print $DataOutput
    ### end of code
    

    输出:

    # data with special string separators
    2019-02-01  123 345 567 Some unpredictable textual data with pipes|,
    2019-02-02  234 345 456 weird symbols @ and commas, and so on.
    2019-02-03  345 234 123 text text text