【问题标题】:How can I remove all text after a character in bash?如何删除bash中一个字符后的所有文本?
【发布时间】:2011-05-09 06:38:20
【问题描述】:

如何在 bash 中删除字符后的所有文本,在本例中为冒号 (":")?我也可以去掉结肠吗?我不知道该怎么做。

【问题讨论】:

    标签: bash


    【解决方案1】:
    egrep -o '^[^:]*:'
    

    【讨论】:

    • 你能解释一下如何解释这个吗,谢谢。
    • egrep 是 grep 与 -E。这与普通的grep 没有区别。 -o 指示 grep 仅打印出与表达式匹配的那部分行。 ^ 将匹配锚定到一行的开头。 [^:]* 匹配零个或多个不是: 字符的字符。 : 匹配字符 :
    【解决方案2】:

    一个例子可能有用,但如果我理解正确的话,这会起作用:

    echo "Hello: world" | cut -f1 -d":"
    

    这会将Hello: world 转换为Hello

    【讨论】:

    • cut 有效,但我丹尼斯的回答更好、更灵活。有谁知道它是否会产生一个像cut 这样的新进程?
    • 使用 Bash 的内置参数扩展功能比生成子shell 运行工具(如 basenamecut)更好,请参阅下面丹尼斯的回答
    • cut 可以从标准输入中读取,因此尤其是当您需要处理很长的字符串(例如文件的内容)时会更好。
    • 这将如何应用于hello: world。这是一半的答案。
    • 它可以使用替换语法来完成,也像 {var/:/''},但只适用于 bash..
    【解决方案3】:

    在 Bash(以及 ksh、zsh、dash 等)中,您可以使用带有 % 的参数扩展,这将删除字符串末尾的字符或 #,它将删除字符串开头的字符.如果您使用其中一个字符,最小的匹配字符串将被删除。如果将字符加倍,最长的将被删除。

    $ a='hello:world'
    
    $ b=${a%:*}
    $ echo "$b"
    hello
    
    $ a='hello:world:of:tomorrow'
    
    $ echo "${a%:*}"
    hello:world:of
    
    $ echo "${a%%:*}"
    hello
    
    $ echo "${a#*:}"
    world:of:tomorrow
    
    $ echo "${a##*:}"
    tomorrow
    

    【讨论】:

    • 这是本机 shell 字符串操作,因此不会产生额外的进程。参考Bash Parameter SubstitutionBash String ManipulationBetter Bash Scripting
    • @denniswilliamson 我怎样才能删除像hello:world 这样的特定字符串之后的两个字符,使用${a%:*} 将变为hello:wo
    • 很好的答案,非常感谢,但也很高兴添加"${a##*:}" 只获得tomorrow =)
    • @openCivilisation:你可能需要使用正则表达式匹配然后:a='hello:world:of:tomorrow'; pattern=''^([^:]*:).*$'; [[ $a =~ $pattern ]];回声“${BASH_REMATCH[1]}”`。仅当有冒号时才匹配。如果您希望它是可选的,则必须使用不同的模式。 Bash 正则表达式(以及一般的正则表达式)的解释超出了这些 cmets 的范围。您可以找到讨论此问题的其他问题或发布您自己的问题。
    • @kp123:这是我回答中的第一个例子。我第二次展示它(“明天”被删除),这几乎就是你要问的情况。
    【解决方案4】:
    $ echo 'hello:world:again' |sed 's/:.*//'
    hello
    

    【讨论】:

      【解决方案5】:

      假设您有一个包含这种格式文件的路径:

      /dirA/dirB/dirC/filename.file
      

      现在您只需要包含四个“/”的路径。类型

      $ echo "/dirA/dirB/dirC/filename.file" | cut -f1-4 -d"/"
      

      你的输出将是

      /dirA/dirB/dirC
      

      使用 cut 的好处是你还可以剪切最上面的目录以及文件(在这个例子中),所以如果你输入

      $ echo "/dirA/dirB/dirC/filename.file" | cut -f1-3 -d"/"
      

      你的输出是

      /dirA/dirB
      

      虽然你可以从字符串的另一端做同样的事情,但在这种情况下,打字并没有多大意义

      $ echo "/dirA/dirB/dirC/filename.file" | cut -f2-4 -d"/"
      

      结果

      dirA/dirB/dirC
      

      在某些其他情况下,最后一种情况也可能会有所帮助。请注意,最后一个输出的开头没有“/”。

      【讨论】:

      • 如果你有一个目录 "/resources/views/admin/users/relationships/posts.blade.php" 并且你想在最后一次出现 "/" 之后截断所有内容,因为您不知道字符串中有多少个“/”字符。所以在这里我希望输出是“/resources/views/admin/users/relationships/”(或者甚至 /resources/views/admin/users/relationships 没有斜杠)。你会怎么做?
      • 一岁多;有一个命令:dirname
      【解决方案6】:

      去掉最后一个“:”之后的所有内容

      grep -o '^.*:' fileListingPathsAndFiles.txt
      

      如果你想删除最后一个“:”

      grep -o '^.*:' file.txt | sed 's/:$//'
      

      @kp123:您希望将: 替换为/(其中sed 冒号应为\/

      【讨论】:

      • 唯一正确的答案。由于此答案删除了 给定的特定字符,因此其他答案也会删除该字符。
      【解决方案7】:

      我知道一些解决方案:

      # Our mock data:
      A=user:mail:password
      
      1. 使用 awk 和管道:
      $ echo $A | awk -v FS=':' '{print $1}'
      user
      
      1. 通过 bash 变量
      $ echo ${A%%:*}
      user
      
      1. 使用管道和 sed
      $ echo $A | sed 's#:.*##g'
      user
      
      1. 使用管道和 grep
      $ echo $A | egrep -o '^[^:]+'
      user
      
      1. 带管道和切割
      $ echo $A | cut -f1 -d\: 
      user
      

      【讨论】:

        猜你喜欢
        • 2017-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-22
        • 2011-05-30
        • 2014-09-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多