使用 Sed Mac 终端查找和替换空格

Posted

技术标签:

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

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

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

.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' 【参考方案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】:

一种方法是使用python 及其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

【讨论】:

以上是关于使用 Sed Mac 终端查找和替换空格的主要内容,如果未能解决你的问题,请参考以下文章

在Mac文件名中用连字符替换空格

使用 sed 进行替换时如何放置空格?

sed 不替换某些空格

关于linux的sed用法。如何替换特殊字符,如IP=192.168.0.1替换成IP=117.112.3.8

shell 查找与替换

shell替换一个或多个空格为逗号