【问题标题】:sed find and replace a specific number [duplicate]sed 查找并替换特定数字[重复]
【发布时间】:2018-11-14 11:49:56
【问题描述】:

我有一个如下文件。

abc  259200000     2     3  864000000     3     5
def  86400000      2    62  864000000     3    62
efg  864000000     2   347          0     0     0
abcd 259200000     3     3          0     0     0

我需要用 Not Exist 替换任何 单个 0。我尝试了关注,但它们都没有工作。

sed 's/[0]/Not Exist/g' data.txt > out.txt
sed 's/[^0]/Not Exist/g' data.txt > out.txt
sed 's/^[0]/Not Exist/g' data.txt > out.txt

非常感谢任何帮助。

【问题讨论】:

    标签: bash shell awk sed


    【解决方案1】:

    如果可以,请尝试关注awk

    awk '{for(i=1;i<=NF;i++){if($i==0){$i="Not Exist"}}}{$1=$1} 1' OFS="\t" Input_file
    

    现在也添加非单线形式的解决方案。

    awk '
    {
      for(i=1;i<=NF;i++){
        if($i==0){
           $i="Not Exist"
        }
      }
    }
    {
      $1=$1
    }
    1
    ' OFS="\t"   Input_file
    

    解释:现在也为上面的代码添加解释。

    awk '
    {
      for(i=1;i<=NF;i++){              ##Starting for loop from variable i=1 to value of NF(number of field) increment with 1 each time.
        if($i==0){                     ##Checking condition if value of field is 0 then do following.
           $i="Not Exist"              ##Re-making value of that field to string Not Exist now.
        }                              ##Closing if condition block now.
      }                                ##Closing for loop block here.
    }
    {
      $1=$1                            ##re-setting first field on current line(to make sure TAB is being made output field separator to edited lines).
    }
    1                                  ##Mentioning 1 means awk works on method on pattern and action. So making condition/pattern as TRUE and not mentioning any action so by default print of current line will happen.
    ' OFS="\t"  Input_file         ##Setting OFS as TAB and mentioning Input_file name here.
    

    【讨论】:

    • 谢谢拉文德。这正是我所期望的。
    • 你能告诉我最后 1 代表什么吗?
    • @buddhima87,很高兴它对您有所帮助,请尝试为有帮助的答案投票。尝试在所有答案中选择正确的答案,请参阅stackoverflow.com/help/someone-answers
    • 当。我们几乎完全相同地键入了相同的 awk 代码。 :)
    • 感谢拉文德。你解释得很好。
    【解决方案2】:

    这就是为什么到目前为止你的三个尝试都不起作用的原因:

    sed 's/[0]/Not Exist/g' data.txt > out.txt
    

    这要求 sed 用替换字符串替换任何零字符,包括那些是较大数字的一部分。

    sed 's/[^0]/Not Exist/g' data.txt > out.txt
    

    这要求 sed 用替换字符串替换任何不为零的字符。 ^“否定”正则表达式括号表达式。

    sed 's/^[0]/Not Exist/g' data.txt > out.txt
    

    这要求 sed 替换行首的任何零,因为在这种情况下,^ 表示“行首的空值”。

    您要查找的内容可能如下表示:

    sed 's/\([[:space:]]\)0\([[:space:]]\)/\1Not exist\2/g; s/\([[:space:]]\)0$/\1Not exist/' data.txt > out.txt
    

    在这个解决方案中,我使用space 字符类,因为我不知道您的输入文件是制表符还是空格分隔。该类同时使用两者,并保留之前的所有内容。

    请注意,这里有两个 sed 命令 - 第一个处理后面有文本的零,第二个处理位于行尾的零。这确实使脚本有点尴尬,所以如果您使用的是更现代的操作系统,其sed 包含-E 选项,则以下内容可能更易于阅读:

    sed -E 's/([[:space:]])0([[:space:]]|$)/\1Not exist\2/g' data.txt > out.txt
    

    这利用了在 ERE 中,一个“原子”可以有多个“分支”,由一个或栏分隔 (|)。更多信息,man re_format

    请注意,sed 可能不是最好的工具。处理字段通常最好用 awk 完成。我无法改进 @RavinderSingh13 的 awk 解决方案,所以如果 awk 是一个选项,你应该使用它。

    当然,几乎任何选项都会使您的格式不稳定。

    【讨论】:

    • 谢谢@ghoti。这帮助我塑造了我的最终输出。
    【解决方案3】:

    我假设列由空格字符分隔,那么:

    使用 sed 时,您需要搜索一个孤立的零,即零“封闭”在空格中。所以你需要检查零前后的字符是否等于空格。您还需要分别处理行上的第一个零和最后一个零。

    sed '
        # replace 0 beeing the first character on the line
        s/^0\([[:space:]]\)/Not Exists\1/
        # replace zeros separated by spaces
        s/\([[:space:]]\)0\([[:space:]]\)/\1Not Exists\2/g
        # replace the last 0
        s/\([[:space:]]\)0&/\1Not Exists/ ' data.txt > out.txt
    

    tutorialpoint 上的实时示例。

    【讨论】:

      【解决方案4】:

      使用 sed:

      sed 's/\<0\>/NotExist/g' file | column -t
      

      \&lt;...\&gt; 匹配一个单词。

      column -t 很好地显示在列中。

      【讨论】:

      • 这也将匹配0 中的0.234(如果有)。空格是这里的界限。
      • 谢谢奥利夫。这是有效的。你能详细说明正则表达式让我理解吗?
      • @WiktorStribiżew 我没有看到任何浮点数输入数据...
      • 如果您认为您的建议是一个解决方案,您应该避免重复发布,因为它已经在stackoverflow.com/questions/1032023stackoverflow.com/questions/46676657...上得到了回答。只需标记为骗子。跨度>
      猜你喜欢
      • 2012-06-24
      • 1970-01-01
      • 1970-01-01
      • 2017-07-15
      • 2014-09-05
      • 2012-03-08
      • 2019-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多