【问题标题】:Remove multiple Spaces - Unix Script删除多个空格 - Unix 脚本
【发布时间】:2019-07-06 14:02:59
【问题描述】:

我试图从我的 shell 脚本中删除重复的空格,但似乎

tr -s " " < input.txt > output.txt 

不工作。有没有其他方法可以将多个连续的空格从 shell 脚本中删除为单个空格。

我正在尝试从内容中删除空格

1     | First         | PO BOX 123        | DAYTON          | OH            | 3432-222
2     | Second        | PO BOX 2223       | CALIFORNIA      | CA            | 23423 
3     | THIRD         | PO BOX 21         | COLUMBUS        | OH            | 2223

进入这个

1|First|PO BOX 123|DAYTON|OH|3432-222
2|Second|PO BOX 2223|CALIFORNIA|CA|23423
3|THIRD|PO BOX 21|COLUMBUS|OH|2223

【问题讨论】:

  • 你确定输入有空格吗? tr 应该有效。试试tr -d '[:blank:]'
  • 再看,看起来你真正想要的只是tr -d \\t,删除标签
  • tr -d '[:blank:]' 有效,但它也在删除地址中的空格(单个空格)
  • 你用的是什么外壳?

标签: unix sed tr


【解决方案1】:

使用最少的sed:

sed 's/ *| */|/g' input.txt 

输出:

1|First|PO BOX 123|DAYTON|OH|3432-222
2|Second|PO BOX 2223|CALIFORNIA|CA|23423 
3|THIRD|PO BOX 21|COLUMBUS|OH|2223

注意:这在功能上与 PaulProgrammer 的答案相同,但由于 input.txt 的空格是纯空格这一事实而简化了" 字符,(没有制表符,)。

【讨论】:

    【解决方案2】:

    尝试使用sed 而不是tr

    sed 's/[[:blank:]]\{1,\}|[[:blank:]]\{1,\}/|/g' < input > output
    

    或者,在 perl 中:

    perl -ne 's#\s+\|\s+#|#g; print;' input > output
    

    【讨论】:

    • 尝试使用 -r 标志,一些 Linux 系统需要它来扩展正则表达式: Like sed -r 's/\s*\|\s*/|/g' 输出.txt
    • \s 是正则表达式的 GNU sed 扩展。此外,+ 是扩展正则表达式 (sed -E/sed -r) 的一部分,或者在 GNU sed 中支持作为 BRE 的扩展,但必须进行转义。所以:GNU sed,BRE:sed 's/\s\+|\s\+/|/g',或 GNU sed,ERE:sed -E 's/\s+\|\s+/|/g'(现在必须转义 |!),或 POSIX:sed 's/[[:blank:]]\{1,\}|[[:blank:]]\{1,\}/|/g'
    • 尝试了所有提供的建议,但似乎没有任何效果。不幸的是,不能使用 perl 并且必须在 shell 脚本中。操作系统版本重要吗?我正在使用 Oracle Enterprise Linux 2.6.39
    • 我相信我的问题与命令应该是不同的。看起来文本文件是在 Windows 中创建的,后来又转移到了 unix,因此任何 sed 和 tr 命令都不起作用。在 unix 中重新生成文件并使用提供的命令似乎可以解决问题。
    【解决方案3】:

    我喜欢将 awk 用于有记录的事物。 tr translates 文本,sed 是一个 streameditor,但 awk 理解记录、字段的概念,字段分隔符等。

    所以要完成你的选项集,这里有一个最小 awk 的解决方案:

    $ awk -F ' *\\| *' '{$1=$1} 1' OFS='|' input.txt
    1|First|PO BOX 123|DAYTON|OH|3432-222
    2|Second|PO BOX 2223|CALIFORNIA|CA|23423
    3|THIRD|PO BOX 21|COLUMBUS|OH|2223
    

    这会将输入字段分隔符设置为-F,并将输出字段分隔符设置为OFS。该脚本由一条语句组成,该语句使用OFS 重写记录,以及一条用于打印该行的语句(1 快捷方式)。

    注意-F 选项中竖线的奇怪转义。如果您要使用它,为避免混淆,您可能希望改为awk -F ' *[|] *' ...

    为了更简洁,以牺牲清晰度为代价,您还可以使用:

    $ awk -F ' *[|] *' '$1=$1' OFS='|' input.txt
    

    这会将记录重写语句转换为应始终返回 true 的条件,从而无需使用 1 快捷方式。虽然它从脚本中删除了一些字符,但我只是为了好玩才包含它;最好使用在一两年内重新阅读时不会让您挠头的代码。 ;)

    【讨论】:

      【解决方案4】:

      我必须在 /etc/servicesfile 中执行类似的操作。

      没有一个 sed 方法对我有用(关于这个问题和许多其他问题)。

      tr -s " " 也什么也没做 tr -s "\t" 删除了一些空格(将其流水线到 tr -s " " 也没有做任何事情)

      我找到的解决方案是使用 'column -t'

       column -t /etc/services | tr -s " " 
      

      据我了解(可能是错误的),column 命令创建了一个表。 -t 定义了列的数量(我认为没有指定,因为它来自输入文件)。然后我可以用 'tr -s " "' 删除所有多余的空格。

      【讨论】:

        猜你喜欢
        • 2011-01-20
        • 2015-05-11
        • 1970-01-01
        • 1970-01-01
        • 2014-02-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多