【问题标题】:sed to python replace extra delimiters in ased 到 python 替换额外的分隔符
【发布时间】:2018-12-21 08:36:03
【问题描述】:

sed 's/\t/_tab_/3g'

我有一个 sed 命令,它基本上替换了我的文本文档中所有多余的制表符分隔符。 我的文档应该是 3 列,但偶尔会有一个额外的分隔符。我无法控制这些文件。

我使用上面的命令来清理文档。但是我对这些文件的所有其他操作都在 python 中。有没有办法在 python 中执行上述 sed 命令?

样本输入:

Column1   Column2         Column3
James     1,203.33        comment1
Mike      -3,434.09       testing testing 123
Sarah     1,343,342.23    there   here

样本输出:

Column1   Column2         Column3
James     1,203.33        comment1
Mike      -3,434.09       testing_tab_testing_tab_123
Sarah     1,343,342.23    there_tab_here

【问题讨论】:

    标签: python csv sed


    【解决方案1】:
    import os
    os.system("sed -i 's/\t/_tab_/3g' " + file_path)
    

    这行得通吗?请注意,上面的 sed 命令有一个 -i 参数,用于就地修改输入文件。

    【讨论】:

    • 我在 Windows 上,不确定如何将 sed 添加到路径中。如果有帮助,请使用 cygwin。老实说,如果可能的话,我真的更喜欢将所有东西都放在 python 程序中。
    【解决方案2】:

    您可以在 python 中模仿sed 行为:

    import re
    
    pattern = re.compile(r'\t')
    string = 'Mike\t3,434.09\ttesting\ttesting\t123'
    replacement = '_tab_'
    count = -1
    spans = []
    start = 2 # Starting index of matches to replace (0 based)
    for match in re.finditer(pattern, string):
        count += 1
        if count >= start:
            spans.append(match.span())
    spans.reverse()
    new_str = string
    for sp in spans:
         new_str = new_str[0:sp[0]] + replacement + new_str[sp[1]:]
    

    现在new_str'Mike\t3,434.09\ttesting_tab_testing_tab_123'

    您可以将其包装在一个函数中并在每一行重复。 但是,请注意,这种 GNU sed 行为不是标准的:

    “数字” 仅替换 REGEXP 的第 NUMBER 个匹配项。

     interaction in 's' command Note: the POSIX standard does not
     specify what should happen when you mix the 'g' and NUMBER
     modifiers, and currently there is no widely agreed upon meaning
     across 'sed' implementations.  For GNU 'sed', the interaction is
     defined to be: ignore matches before the NUMBERth, and then match
     and replace all matches from the NUMBERth on.
    

    【讨论】:

      【解决方案3】:

      你可以逐行读取文件,用tab分割,如果超过3个,将第3个之后的项目用_tab_连接起来:

      lines = []
      with open('inputfile.txt', 'r') as fr:
          for line in fr:
              split = line.split('\t')
              if len(split) > 3:
                  tmp = split[:2]                      # Slice the first two items
                  tmp.append("_tab_".join(split[2:]))  # Append the rest joined with _tab_
                  lines.append("\t".join(tmp))         # Use the updated line
              else:
                  lines.append(line)                   # Else, put the line as is
      

      Python demo

      lines 变量将包含类似

      Mike    -3,434.09   testing_tab_testing_tab_123
      Mike    -3,434.09   testing_tab_256
      No  operation   here
      

      【讨论】:

        猜你喜欢
        • 2021-06-25
        • 2021-10-25
        • 2013-05-25
        • 2016-12-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多