sed查找并替换一个特定的数字

时间:2018-11-14 11:49:56

标签: bash shell awk sed

我有一个如下文件。

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

我需要用单词不存在替换任何单个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

非常感谢您的帮助。

4 个答案:

答案 0 :(得分:3)

如果可以,请尝试使用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 :(得分: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替换行首的任何零,因为在这种情况下^的意思是“行首的null”。

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

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是一种选择,则应使用该解决方案。

当然,几乎所有选项都将使您的格式变笨。

答案 2 :(得分:1)

我假设这些列由空格字符分隔,然后:

使用sed时,您需要搜索一个孤独的零,即零“封闭”在空格中。因此,如果等于空格,则需要在零之前和之后检查char。另外,您需要分别处理该行的第一个零和最后一个零。

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上的实时示例。

答案 3 :(得分:0)

使用sed:

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

\<...\>与一个单词匹配。

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