【问题标题】:How to remove the last character from a bash grep output如何从 bash grep 输出中删除最后一个字符
【发布时间】:2011-07-01 18:52:42
【问题描述】:
COMPANY_NAME=`cat file.txt | grep "company_name" | cut -d '=' -f 2` 

输出类似这样的东西

"Abc Inc";

我想要做的是我想删除尾随的“;”也是。我怎样才能做到这一点?我是 bash 的初学者。任何想法或建议都会有所帮助。

【问题讨论】:

  • 这里也一样。 cat/grep = grep.
  • 对于手头的问题,可以用 grep 解决: COMPANY_NAME=$(grep -Po '(?

标签: bash grep


【解决方案1】:
cat file.txt | grep "company_name" | cut -d '=' -f 2 | cut -d ';' -f 1

【讨论】:

  • 这很明显!抱歉我忽略了这个明显的事情。
  • 正如 linus torvalds 所说,程序员最难找到的东西之一就是“好品味”,这很难定义。但既然你会从中受益,我会在这种情况下这样做:因为最初的cat 管道中真正工作的每个元素都在其标准输入和标准输出上运行。好处是您可以将cat 替换为产生类似于file.txt 的输出的其他管道,并且您甚至不必更改管道功能部分中的单个字符。这允许插入式管道可重用性。
  • @Det fyb 上面(忘记给你打标签,就像有人在编写管道时可能忘记删除输入参数并想知道为什么输出不符合预期)
  • @randomstring,虽然我没有真正看到这一点,因为你给了我一个 "piece of your mind"(顺便说一句,我很高兴)保留 cat 的使用是相当极端的可重用性只是为了让您以后可以将其更改为其他内容。我认为它唯一值得的是简单。如果用户键入grep pattern file,那么我非常确定他明白这是读取文件的第一部分以及他开始管道的位置。
  • @randomstring 远非如此。
【解决方案2】:

不必链接这么多工具。只需一个 awk 命令即可完成这项工作

 COMPANY_NAME=$(awk -F"=" '/company_name/{gsub(/;$/,"",$2) ;print $2}' file.txt)

【讨论】:

    【解决方案3】:

    我会使用sed 's/;$//'。例如:

    COMPANY_NAME=`cat file.txt | grep "company_name" | cut -d '=' -f 2 | sed 's/;$//'`
    

    【讨论】:

    • 不要滥用cats。 grep 居然可以读取文件,你知道吗? ;-)
    • @Anony-Mousse 是的,我知道这里至少有两种方法可以避免cat。我留在 cat 中是为了避免将命令行从问题中更改为超出使其正常工作所必需的内容。
    • @Anony-Mousse 并非在所有情况下,简单的 grep 没有 cat -v 将隐藏不可见(例如恶意)字符,unix.stackexchange.com/questions/202198/…
    【解决方案4】:

    在 Bash 中仅使用一个外部实用程序:

    IFS='= ' read -r discard COMPANY_NAME <<< $(grep "company_name" file.txt)
    COMPANY_NAME=${COMPANY_NAME/%?}
    

    【讨论】:

      【解决方案5】:

      这将删除您的 COMPANY_NAME 变量中包含的最后一个字符,无论它是否为分号:

      echo "$COMPANY_NAME" | rev | cut -c 2- | rev
      

      【讨论】:

        【解决方案6】:

        假设引号实际上是输出的一部分,您不能只使用 -o 开关返回引号之间的所有内容吗?

        COMPANY_NAME="\"ABC Inc\";" | echo $COMPANY_NAME | grep -o "\"*.*\""
        

        【讨论】:

          【解决方案7】:

          不要滥用cats。你知道grep 也可以读取文件吗?

          规范的方法是这样的:

          grep "company_name" file.txt | cut -d '=' -f 2 | sed -e 's/;$//'
          

          更聪明的方法是使用单个 perlawk 语句,它们可以同时进行过滤和不同的转换。例如这样的:

          COMPANY_NAME=$( perl -ne '/company_name=(.*);/ && print $1' file.txt )
          

          【讨论】:

            【解决方案8】:

            使用sed,如果您不知道最后一个字符实际上是什么:

            $ grep company_name file.txt | cut -d '=' -f2 | sed 's/.$//'
            "Abc Inc"
            

            【讨论】:

            • 我认为您不需要\{1\},因为. 表示单个字符。
            【解决方案9】:

            我没有发现 sed 's/;$//' 有效。它没有修剪任何东西,但我想知道是否是因为我试图修剪的角色恰好是“$”。对我有用的是sed 's/.\{1\}$//'

            【讨论】:

              【解决方案10】:
              foo="hello world"
              echo ${foo%?}
              hello worl
              

              【讨论】:

              • 这是 bash 方式,而不是其他管道装置。
              • 我喜欢。添加额外的?删除更多字符。
              • 这让我很开心,因为我试图快速而肮脏地列出我们拥有 TLS 密钥的网站。 for L in `ls *key` ; do echo ${L%.key} ; done
              【解决方案11】:

              我相信用 bash 从字符串中去除单个字符的最简洁方法是:

              echo ${COMPANY_NAME:: -1}
              

              但我无法将 grep 片段嵌入花括号中,因此您的特定任务变成了一个两行:

              COMPANY_NAME=$(grep "company_name" file.txt); COMPANY_NAME=${COMPANY_NAME:: -1} 
              

              这将删除任何字符,分号与否,但也可以专门删除分号。 要删除所有分号,无论它们落在哪里:

              echo ${COMPANY_NAME/;/}
              

              只删除末尾的分号:

              echo ${COMPANY_NAME%;}
              

              或者,从末尾删除多个分号:

              echo ${COMPANY_NAME%%;}
              

              有关此方法的详细信息和更多信息,Linux 文档项目在http://tldp.org/LDP/abs/html/string-manipulation.html 上介绍了很多内容

              【讨论】:

              • 第一个对我不起作用,但 echo ${var:0:-1} 对我有用
              【解决方案12】:

              我会使用head --bytes -1,或者简称为head -c-1

              COMPANY_NAME=`cat file.txt | grep "company_name" | cut -d '=' -f 2 | head --bytes -1`
              

              head 仅输出流或文件的开头。通常它会计算行数,但可以改为计算字符/字节数。 head --bytes 10 将输出前十个字符,但head --bytes -10 将输出除最后十个以外的所有字符。

              注意:如果最后一个字符是多字节的,您可能会遇到问题,但分号不是

              我会推荐这个解决方案而不是 sedcut,因为

              • 这正是 head 的设计初衷,因此命令行选项更少,命令更易于阅读
              • 它让您不必考虑正则表达式,这些正则表达式很酷/很强大,但往往过于矫枉过正
              • 它让您的机器不必考虑正则表达式,因此速度会不知不觉地变快

              【讨论】:

              • 我已经测试了另一个建议的解决方案,这对于我的用例来说似乎是最好的(也是一个简单的!)。谢谢!
              • 在 OSX brew install coreutils 然后你可以使用ghead -c-1
              【解决方案13】:

              你可以使用这个 bash 结构将字符串的开头和结尾去掉 N 个字符,正如有人已经说过的那样

              $ fred=abcdefg.rpm
              $ echo ${fred:1:-4}
              bcdefg
              

              但是,旧版本的 bash 不支持此功能。我刚刚发现为 Red hat EL6 安装过程编写脚本。这是在这里发帖的唯一原因。 实现此目的的一个 hacky 方法是将 sed 与扩展的正则表达式一起使用,如下所示:

              $ fred=abcdefg.rpm
              $ echo $fred | sed -re 's/^.(.*)....$/\1/g'
              bcdefg
              

              【讨论】:

                【解决方案14】:

                上面回答的一些改进。要删除多个字符,请添加多个问号。例如,要从变量 $SRC_IP_MSG 中删除最后两个字符,您可以使用:

                SRC_IP_MSG=${SRC_IP_MSG%??}
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2012-09-21
                  • 2021-05-10
                  • 2023-04-06
                  • 1970-01-01
                  • 2015-02-23
                  • 1970-01-01
                  • 2020-03-12
                  • 2021-12-11
                  相关资源
                  最近更新 更多