【问题标题】:Find and Replace with Spaces using Sed Mac Terminal使用 Sed Mac 终端查找和替换空格
【发布时间】:2013-09-21 07:41:40
【问题描述】:

我有一个包含超过 500,000 行的 .CSV 文件,我需要:

  1. 查找所有“空格双引号空格”序列并替换为空
  2. 查找所有“空格双引号”序列并替换为空
  3. 查找所有双引号并替换为空

.CSV 行示例:

"DISH Hartford & New Haven  (Hartford)", "206", "FBNHD", " 06028", " East Windsor Hill", "CT", "Hartford County"

** 所需输出**

DISH Hartford & New Haven  (Hartford),206,FBNHD,06028,East Windsor Hill,CT,Hartford County

我需要删除所有双引号 (") 和逗号前后的空格 (,)。

我试过了

$ cd /Users/Leonna/Downloads/
$ cat bs-B2Bformat.csv | sed s/ " //g

这给了我比提示更大的“命令不完整”,所以我尝试了:

$ cat bs-B2Bformat.csv | sed s/ " //g
sed: 1: "s/": unterminated substitute pattern
$ cat bs-B2Bformat.csv |sed s/ \" //g
sed: 1: "s/": unterminated substitute pattern
$

我在 Excel 中编辑的行太多(Excel 不会加载所有行)甚至是文本编辑器。我该如何解决这个问题?

【问题讨论】:

  • 编辑了我的答案。应该这样做...
  • 一般评论 — 将 sed 脚​​本括在单引号中。例如:sed 's/ " //g'。唯一不这样做的情况是……也许……当命令本身需要包含单引号时,通常最好将每个文字单引号写成'\'',所以你可以写sed 's/ '\'' //g'

标签: macos bash csv sed terminal


【解决方案1】:

所有当前答案似乎都错过了:

$ cat bs-B2Bformat.csv | sed s/ " //g
sed: 1: "s/": unterminated substitute pattern
$ cat bs-B2Bformat.csv |sed s/ \" //g
sed: 1: "s/": unterminated substitute pattern
$

上面的问题是缺少单引号。应该是:

$ cat bs-B2Bformat.csv | sed 's/ " //g'
                             ^        ^

如果没有单引号,bash 会在空格处拆分并发送三个单独的参数(至少对于\" 而言)。 sed 将其第一个参数视为 s/

编辑:仅供参考,单引号不是必需的,它们只是使这种情况更容易。如果要使用双引号,只需转义要保留以进行匹配的那个:

$ cat bs-B2Bformat.csv | sed "s/ \" //g"

【讨论】:

    【解决方案2】:

    一种方法是使用 及其csv 模块:

    import csv 
    import sys 
    
    ## Open file provided as argument.
    with open(sys.argv[1], 'r') as f:
    
        ## Create the csv reader and writer. Avoid to quote fields in output.
        reader = csv.reader(f, skipinitialspace=True)
        writer = csv.writer(sys.stdout, quoting=csv.QUOTE_NONE, escapechar='\\')
    
        ## Read file line by line, remove leading and trailing white spaces and
        ## print.
        for row in reader:
            row = [field.strip() for field in row]
            writer.writerow(row)
    

    像这样运行它:

    python3 script.py csvfile
    

    产生:

    DISH Hartford & New Haven  (Hartford),206,FBNHD,06028,East Windsor Hill,CT,Hartford County
    

    【讨论】:

      【解决方案3】:

      引用自here

      为了符合 POSIX,使用字符类 [[:space:]] 代替 \s,因为后者是 GNU sed 扩展。

      基于此,我建议如下,正如Jonathan Leffler 指出的那样,它可以跨 GNU 和 BSD 实现移植。

      sed -E 's/[[:space:]]?"[[:space:]]?//g' <path/to/file>
      

      -E 标志在 BSD 实现上启用扩展正则表达式。在 GNU sed 上,它没有被记录,但正如 here 所讨论的,它可以与 BSD 标准兼容。

      引自manual for BSD sed

      -E 将正则表达式解释为扩展(现代)正则 表达式而不是基本的正则表达式 (BRE)。

      对包含以下单行的文件应用上述命令

      “DISH 哈特福德和纽黑文(哈特福德)”、“206”、“FBNHD”、“06028”、“东温莎山”、“CT”、“哈特福德县”

      它产生了

      DISH Hartford & New Haven (Hartford),206,FBNHD,06028,East Windsor Hill,CT,Hartford County

      【讨论】:

      • 这依赖于 GNU sed。问题提到了Mac。对于 Mac sed,您必须为备份指定一个后缀(例如 -i.bak)。此外,Mac sed 默认不解释 ERE;您必须使用-E 启用它们。问号前面的反斜杠也不是必需的。所以,在 Mac 上,这行得通:sed -E 's/[[:space:]]?"[[:space:]]?//g(同时使用 BSD 和 GNU sed 命令)——显然不会覆盖文件,但如果需要,您可以添加 -i.bak
      • 这绝对是正确的答案。 \s 不适用于 OSX。
      【解决方案4】:

      这对我有用。这是你想要的吗?

       sed -e 's|", "|,|g' -e 's|^"||g' -e 's|"$||g' file.csv
      
       echo '"DISH Hartford & New Haven (Hartford)", "206", "FBNHD", " 06028", " East Windsor Hill", "CT", "Hartford County"' | sed -e 's|", "|,|g' -e 's|^"||g' -e 's|"$||g'
      
       DISH Hartford & New Haven (Hartford),206,FBNHD, 06028, East Windsor Hill,CT,Hartford County
      

      【讨论】:

        【解决方案5】:

        应该这样做:

        sed -i 's/\(\s\|\)"\(\|\s\)//g' bs-B2Bformat.csv
        

        【讨论】:

          猜你喜欢
          • 2020-08-05
          • 2013-12-18
          • 2014-09-05
          • 2021-10-06
          • 1970-01-01
          • 2019-11-29
          • 2014-06-22
          • 2018-10-01
          • 2017-11-11
          相关资源
          最近更新 更多