【问题标题】:Delete _ and - characters using sed使用 sed 删除 _ 和 - 字符
【发布时间】:2015-08-19 17:53:05
【问题描述】:

我正在尝试使用 sed 将 2015-06-03_18-05-30 转换为 20150603180530

我有这个:

$ var='2015-06-03_18-05-30'
$ echo $var | sed 's/\-\|\_//g'
$ echo $var | sed 's/-|_//g'

这些都不起作用。为什么交替不起作用?

【问题讨论】:

  • 一般来说,“我如何使用 Y 做 X”比“做 X 的最佳方法是什么?”是一个更糟糕的问题,因为它假设一个答案。这个答案可能不正确。现在,如果你解释为什么你想做Y(“只使用内置工具”;“只使用我的操作系统附带的工具”),这是明智的,并且让人们建议其他工具符合相同的限制。
  • (另外,在此处的示例中,您不想“替换”这些字符,而是要删除它们;用空字符串替换某些内容是 one 方式删除它,但不是唯一的方法;使用暗示特定方法的词同样排除其他方法)。
  • ...或者,如果您真正的问题是“为什么这种正则表达式语法在这种情况下不起作用?”,这是一个合法的问题,但我建议直接问。
  • @CharlesDuffy 我不完全同意你的第一条评论。我总体上同意这个想法,但在 SO 人工作的情况下不同意,我的意思是每次有人问如何做到这一点,人们评论并要求放置代码而不是问 howto (通常是接近动作太宽泛不清楚)。因此,似乎请求应该是我尝试...在这些约束下...我尝试这个失败...
  • @NeronLeVelu,我没有说不要包含尝试过的示例。在这种情况下,使用sed 显示一个人的尝试是完全合适的,可以建立上下文,并且也足以防止关闭。将可接受的答案集限制为仅满足 OP 关于他们如何自己解决问题的最初期望的答案在这一点上没有进一步的好处。当然,尽管如此,我同意应该包括合法的环境限制——但要明确其原因和性质(即“仅使用 POSIX 工具”)。

标签: linux bash shell sed sh


【解决方案1】:

简单:

sed 's/[-_]//g' 

字符类[-_] 匹配集合中的字符。

【讨论】:

  • 我错过的文档中是否有正式的规则?
  • 信息 sed | grep -C 3 \\\\w 将为\w解释(与此问题无关)
【解决方案2】:

应该这样做。

sed 's/[-_]//g'

这读作:

  1. s:搜索
  2. /[-_]/:用于匹配-_ 的任何单个字符
  3. //: 什么都不换
  4. g: 对行中的每个字符都这样做

默认情况下,Sed 对每一行都进行操作,因此它涵盖了文件/字符串中的每个实例。

【讨论】:

  • @abc:交替表示法不起作用,因为sed 不能识别扩展的 RE,除非你告诉它——事实上,sed 的某些版本可能根本无法识别它们。正则表达式有多种方言,sed的默认比较原始。
【解决方案3】:

我知道您要求使用 sed 提供解决方案,但我在 tr 中提供了替代方案:

$ var='2015-06-03_18-05-30'
$ echo $var | tr -d '_-'
20150603180530

tr 应该快一点。

解释:

  • tr 代表翻译,它可用于将某些字符替换为另一个字符。
  • -d 选项代表 delete,它会删除指定的字符而不是替换它们。
  • '_-' 指定要删除的字符集(也可以指定为 '\-_',但您需要在此处转义 -,否则它被视为另一个选项)。

【讨论】:

  • 完全不使用外壳外部的任何东西会更快。
【解决方案4】:

只要你的脚本有#!/bin/bash(或ksh,或zsh)shebang,不要使用sed tr:你的shell可以在没有启动任何外部工具的(相对较大的)开销:

var='2015-06-03_18-05-30'
echo "${var//[-_]/}"

也就是说,如果你真的想使用sed,GNU 扩展-r 会启用ERE 语法:

$ sed -r -e 's/-|_//g' <<<'2015-06-03_18-05-30'
20150603180530

有关 BRE(sed 的默认设置)和 ERE 之间差异的讨论,请参阅 http://www.regular-expressions.info/posix.html。该页面在讨论 ERE 扩展时指出:

通过常用的竖线|支持交替。


如果你想在 POSIX 平台上工作——使用/bin/sh 而不是 bash,并且没有 GNU 扩展——然后重新编写你的正则表达式以使用字符类(并且,为了避免 platform-dependent compatibility issues with echo[1] ,请改用printf):

printf '%s\n' "$var" | sed 's/[-_]//g'

[1] - 请特别参阅该链接的“应用程序使用”部分。

【讨论】:

    【解决方案5】:
    sed 's/[^[:digit:]]//g' YourFile
    

    你能告诉我在echo $var | sed 's/\-\|\_//g' 上失败的原因吗,它在这里可以工作(即使不需要转义-_ 并且假设你使用GNU sed,因为\| 只能在这个增强版本中工作sed)

    【讨论】:

      猜你喜欢
      • 2017-05-28
      • 2016-04-17
      • 2020-11-03
      • 1970-01-01
      • 2011-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多