【问题标题】:How can I strip first X characters from string using sed?如何使用 sed 从字符串中删除前 X 个字符?
【发布时间】:2012-07-13 06:35:52
【问题描述】:

我正在一个小型工业机器中为嵌入式 Linux 编写 shell 脚本。我有一个包含文本 pid: 1234 的变量,我想从该行中删除前 X 个字符,因此只保留 1234 个字符。我有更多变量需要“清理”,因此我需要删除 X 的第一个字符,而 ${string:5} 在我的系统中由于某种原因无法正常工作。

盒子里似乎只有sed

我正在尝试使以下工作:

result=$(echo "$pid" | sed 's/^.\{4\}//g')

有什么想法吗?

【问题讨论】:

  • 如果 ${string:5} 不起作用,那么您没有使用 Bash 或其他支持该语法的 shell。您使用的是什么外壳和版本?你的shebang是什么样子的?我的猜测是您使用的是sh(例如dash)或者可能是zsh

标签: bash shell sed


【解决方案1】:

我在this question 提供的纯 sed 中找到了答案(诚然,在发布此问题后发布)。这完全符合您的要求,仅在 sed 中:

result=\`echo "$pid" | sed '/./ { s/pid:\ //g; }'\``

sed '/./) 中的点是您想要匹配的任何内容。您的问题正是我试图解决的问题,除了在我的情况下,我想匹配文件中的特定行然后取消注释。在我的情况下是:

# Uncomment a line (edit the file in-place):
sed -i '/#\ COMMENTED_LINE_TO_MATCH/ { s/#\ //g; }' /path/to/target/file

sed 之后的-i 用于就地编辑文件(如果您想在编辑文件之前测试匹配的表达式,请删除此开关)。

(我发布这个是因为我想完全用 sed 来完成这个问题,而之前的回答都没有解决这个问题。)

【讨论】:

    【解决方案2】:

    这是使用cut(1) 剪切前X 个字符的简洁方法。此示例通过剪切从第 5 个字符开始的子字符串来删除前 4 个字符。

    echo "$pid" | cut -c 5-
    

    【讨论】:

    • 从技术上讲,OP 要求使用 sed,但我觉得这是“如何从字符串 [in a terminal/bash] 中删除前 X 个字符”与 git 结合使用时的最佳解决方案,很好:git log --pretty=oneline | cut -c 42- | head
    • +1 简单而有用的解决方案.. 当我的 URL 为 http:// 并削减协议“http://”时,我不得不改为 8 个字符7。我不知道,但这就是它对我的工作方式。
    • Santosh Kumar Arjunan:那是因为示例 "echo "$pid" | cut -c 4-" 实际上没有剪切前 4 个字符,而是从第 4 个字符开始提取子字符串。因此它实际上削减了前 3 个字符。因此,如果要剪切 7 个第一个字符,则要从第 8 个字符中提取所有内容,因此确实要执行 "cut -c 8-"
    • 我该如何做 cut -c $LEN- 这样我可以传递变量中的金额?
    • @DeanHiller cut -c ${LEN}-。花括号用于将字符串与有效的变量字符连接起来,以区分什么是变量,什么不是。如果您想了解更多信息,请查看“bash 变量字符串连接”以获取有关其工作原理/方式的更多资源。
    【解决方案3】:

    从字符串中删除前两个字符:

    $ string="1234567890"; echo "${string:2}"
    34567890
    

    【讨论】:

    • @dtp70 非常感谢一个通用的答案,效果很好!
    【解决方案4】:

    嗯,这里有sedawkcut 和使用bash 语法的解决方案。我只想加入另一个符合 POSIX 的变体:

    $ echo "pid: 1234" | tail -c +6
    1234
    

    -c 告诉tail 从哪个字节偏移开始,从输入数据的末尾开始计数,但是如果数字以+ 符号开头,则它是从输入数据的开头到结尾。

    【讨论】:

    • 我真的很喜欢这个答案,因为它完全满足 OP 的要求,而无需使用过于复杂的工具。
    【解决方案5】:

    也许您可以直接提取数字,而不是从一开始就删除 n 个字符。就这样……

    $ echo "pid: 1234" | grep -Po "\d+"
    

    这可能是一个更强大的解决方案,并且看起来更直观。

    【讨论】:

      【解决方案6】:

      以下应该有效:

      var="pid: 1234"
      var=${var:5}
      

      您确定bash 是执行您的脚本的shell 吗?

      即使是符合 POSIX 标准的

      var=${var#?????}
      

      会比使用外部进程更可取,尽管这需要您以固定长度模式的形式对 5 进行硬编码。

      【讨论】:

      • 您还可以使用第二个参数指定长度:${var:5:2} 将从1 开始并返回12
      【解决方案7】:

      另一种方式,使用cut 而不是sed

      result=`echo $pid | cut -c 5-`
      

      【讨论】:

      • 他想删除前 4 个字符。这将获取前 4 个字符。
      【解决方案8】:

      通过awk '{print substr($0,42)}' 传递它,其中 42 比要删除的字符数多一。例如:

      $ echo abcde| awk '{print substr($0,2)}'
      bcde
      $
      

      【讨论】:

        【解决方案9】:

        很有可能,您也会拥有cut。如果是这样:

        [me@home]$ echo "pid: 1234" | cut -d" " -f2
        1234
        

        【讨论】:

        • cut 的问题在于它不能明智地处理空白序列,使用tr -s ' ' 来“挤压”空格使其表现更好。
        • 它不是一个会唱歌跳舞的工具;它很简单,正如它在罐头上所说的那样,并且可以广泛使用。它应该可以很好地满足上述要求,并且肯定比从特定位置裁剪固定字符更健壮。
        【解决方案10】:

        sed 使用-r 选项(“在脚本中使用扩展的正则表达式”)以使用{n} 语法:

        $ echo 'pid: 1234'| sed -r 's/^.{5}//'
        1234
        

        【讨论】:

        • 如果我想从字符串中删除最后 X 个字符,情况会怎样?
        • @Kokesh: 你可以用sed -r 's/.{5}$//' 去掉最后 5 个字符
        • 如果你转义大括号,你可以不使用-r(OS X 中的-E,IIRC)(但不知道这是否适用于 OS X)。
        【解决方案11】:

        这也可以完成这项工作:

        echo "$pid"|awk '{print $2}'
        

        【讨论】:

        • 这个问题是“跳过字符串中的前 N ​​个字符”的第一个问题。你没有回答问题。
        • 这似乎行不通,如果行,你能解释一下如何
        • 它在我的系统上运行。您的字段分隔符可能有问题,请尝试awk -F": " '{print $2}'。不过,这不是我最喜欢的解决方案。
        猜你喜欢
        • 2012-08-02
        • 2012-04-09
        • 2013-05-09
        • 2011-11-03
        • 1970-01-01
        • 2017-05-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多