【问题标题】:Remove from the beginning till certain part in a string从开头删除直到字符串中的某个部分
【发布时间】:2011-09-16 12:23:31
【问题描述】:

我使用类似的字符串

abc_dsdsds_ss_gsgsdsfsdf_ewew_wewewewewew_adf

我需要得到一个新的,从原始字符串中删除从开头到最后出现“_”和下一个字符(可以是 3、4 或任何数字)的所有内容

所以在这种情况下我会得到

_adf

我如何使用“sed”或其他 bash 工具来做到这一点?

【问题讨论】:

    标签: perl string bash sed awk


    【解决方案1】:
    sed 's/^(.*)_([^_]*)$/_\2/' < input.txt
    

    【讨论】:

    • 很好的解决方案。但是,您根本不需要第一组,并且忘记了反斜杠括号。不过,我敢打赌,如果您将 -e 标志传递给 GNU sed,您可以使用非反斜杠括号。
    • 很公平。无论如何,在通过 sed 命令进行黑客攻击时,我几乎都会随机添加反斜杠。
    【解决方案2】:

    只需用\(_[^_]*\) 将最后一个非下划线字符分组,然后用\1 引用该组:

     sed 's/^.*\(_[^_]*\)$/\1/'
    

    结果:

    $ echo abc_dsdsds_ss_gsgsdsfsdf_ewew_wewewewewew_adf | sed 's/^.*\(_[^_]*\)$/\1/'
    _adf
    

    【讨论】:

      【解决方案3】:

      您需要修改字符串,还是只查找最后一个下划线之后的所有内容?查找最后一个 _{anything} 的正则表达式将是 /(_[^_]+)$/($ 匹配字符串的结尾),或者如果您还想匹配后面没有任何内容的尾随下划线,/(_[^_]*)$/

      除非你真的需要修改字符串而不是仅仅找到这个片段,或者你真的想从命令行而不是脚本来做这个,这个正则表达式有点简单(你用 perl 标记了这个,所以我不太确定只使用命令行而不是使用简单的脚本)。

      如果您确实需要修改字符串,sed -i 's/(_[^_]+)$/\1/' myfilesed -i 's/(_[^_]+)$/\1/g' myfile-i(编辑:我决定不要偷懒并查找正确的语法......)-i 标志只会用新文件覆盖旧文件。如果你想创建一个新文件而不是破坏旧文件,sed -e 's/.../.../g' oldfile &gt; newfiles/// 之后的 g 将为您传递给 sed 的文件中的所有实例执行此操作;省略它只会替换第一个实例。

      如果字符串本身不是位于行尾,而是嵌入到其他文本中。但只是用空格分隔,将$ 替换为\s,它将匹配一个空格字符(单词的结尾)。

      【讨论】:

      • 他/她想从 bash 中调用它,所以没有真正的区别。
      • 是的,在写下我的第一个简短答案后,我意识到......并且它从那里开始发展。实际上,很好的电话,我的措辞有点不对劲。固定的。谢谢。
      【解决方案4】:

      在 Perl 中,您可以这样做:

      my $string = "abc_dsdsds_ss_gsgsdsfsdf_ewew_wewewewewew_adf";
      
      if ( $string =~ m/(_[^_]+)$/ ) {
          print $1;
      }
      

      [编辑] 一种 Perl 单行方法(即,可以直接从 bash 运行):

      perl -lne 'm/(_[^_]+)$/ && print $1;' infile > outfile
      

      或者使用替换:

      perl -pe 's/.*(_[^_]+)$/$1/' infile > outfile
      

      【讨论】:

        【解决方案5】:

        一种 Perl 方式:

        echo 'abc_dsdsds_ss_gsgsdsfsdf_ewew_wewewewewew_adf' | \
        perl -e 'print ((split/(_)/,<>)[-2..-1])'
        

        输出:

        _adf
        

        【讨论】:

          【解决方案6】:

          正则表达式模式匹配是贪婪的。因此 ^.*_ 将匹配直到并包括最后一个 _ 的所有字符。然后把下划线放回去:

          echo abc_dsdsds_ss_gsgsdsfsdf_ewew_wewewewewew_adf | sed 's/^.*_/_/'
          

          【讨论】:

            【解决方案7】:

            如果你在 bash 变量中有这样的字符串(我没有看到问题中指定的),你可以使用parameter expansion:

            s="abc_dsdsds_ss_gsgsdsfsdf_ewew_wewewewewew_adf"
            t="_${s##*_}"
            echo "$t"  # ==> _adf
            

            【讨论】:

              【解决方案8】:

              只是为了好玩:

              echo abc_dsdsds_ss_gsgsdsfsdf_ewew_wewewewewew_adf | tr _ '\n' | tail -n 1 | rev | tr '\n' _ | rev
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2019-11-15
                • 1970-01-01
                • 2021-08-23
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2010-09-08
                相关资源
                最近更新 更多