特定字段中的awk搜索模式并替换其内容

特定字段中的awk搜索模式并替换其内容,awk,Awk,我需要找到一个空的密码字段,带有空格或制表符,并用x替换它(在/etc/passwd文件中) awk -F":" '($2 == "" || $2 == " " || $2 == "\t") {print $0}' $file 我在awk中发现了这种语法,它向用户显示第二个字段(使用:作为分隔符)是空的还是空的,或者其中有空格或制表符: awk -F":" '($2 == "" || $2 == " " || $2 == "\t") {print $0}' $file 结果如下: awk -

我需要找到一个空的密码字段,带有空格或制表符,并用x替换它(在/etc/passwd文件中)

awk -F":" '($2 == "" || $2 == " " || $2 == "\t") {print $0}' $file
我在awk中发现了这种语法,它向用户显示第二个字段(使用:作为分隔符)是空的还是空的,或者其中有空格或制表符:

awk -F":" '($2 == "" || $2 == " " || $2 == "\t") {print $0}' $file
结果如下:

awk -F":" '($2 == "" || $2 == " " || $2 == "\t") {print $0}' $file
user1::53556:100::/home/user1:/bin/bash
user2: :53557:100::/home/user2:/bin/bash
user3:  :53558:100::/home/user3:/bin/bash

我怎么能对awk说用另一个字符替换第二个字段(空白或空格或制表符)?(例如x)

请尝试以下内容

awk -F":" '($2 == "" || $2 == " " || $2 == "\t") {print $0}' $file
awk 'BEGIN{FS=OFS=":"} {$2=$2=="" || $2~/^[[:space:]]+$/?"X":$2} 1' Input_file
awk '
BEGIN{
  FS=OFS=":"
}
prev{
  num=split(prev,array,":")
  array[2]=array[2]=="" || array[2]~/^[[:space:]]+$/?"X":array[2]
  for(i=1;i<=num;i++){
    val=(val?val OFS array[i]:array[i])
  }
  print val
  val=""
}
{
  prev=$0
}
END{
  if(prev){
    print prev
  }
}'  Input_file
解释:添加上述代码的解释

awk -F":" '($2 == "" || $2 == " " || $2 == "\t") {print $0}' $file
awk '                                          ##Starting awk program here.
BEGIN{                                         ##Starting BEGIN section here which will be executed before Input_file is being read.
  FS=OFS=":"                                   ##Setting FS and OFS as colon here for all lines of Input_file.
}                                              ##Closing BEGIN section block here.
{
  $2=$2=="" || $2~/^[[:space:]]+$/?"X":$2      ##Checking condition if $2(2nd field) of current line is either NULL or having complete space in it then put its vaklue as X or keep $2 value as same as it is.
}
1                                              ##mentioning 1 will print edited/non-edited current line.
' Input_file                                   ##Mentioning Input_file name here.
$ awk 'BEGIN{FS=OFS=":"} (NF>1) && ($2~/^[[:space:]]*$/){$2="x"} 1' file
user1:x:53556:100::/home/user1:/bin/bash
user2:x:53557:100::/home/user2:/bin/bash
user3:x:53558:100::/home/user3:/bin/bash


编辑:根据OP,OP无需触摸输入文件的最后一行,因此现在添加以下解决方案

awk -F":" '($2 == "" || $2 == " " || $2 == "\t") {print $0}' $file
tac Input_file | awk 'BEGIN{FS=OFS=":"} FNR==1{print;next} {$2=$2=="" || $2~/^[[:space:]]+$/?"X":$2} 1' | tac


EDIT2:如果您想在awk
awk
本身中执行此操作,请尝试以下操作

awk -F":" '($2 == "" || $2 == " " || $2 == "\t") {print $0}' $file
awk 'BEGIN{FS=OFS=":"} {$2=$2=="" || $2~/^[[:space:]]+$/?"X":$2} 1' Input_file
awk '
BEGIN{
  FS=OFS=":"
}
prev{
  num=split(prev,array,":")
  array[2]=array[2]=="" || array[2]~/^[[:space:]]+$/?"X":array[2]
  for(i=1;i<=num;i++){
    val=(val?val OFS array[i]:array[i])
  }
  print val
  val=""
}
{
  prev=$0
}
END{
  if(prev){
    print prev
  }
}'  Input_file
awk'
开始{
FS=OFS=“:”
}
上{
num=split(上一个,数组“:”)
数组[2]=数组[2]==“| |数组[2]~/^[:空格:]+$/?“X”:数组[2]
对于(i=1;i
要使用GNU awk更改原始文件,请执行以下操作:

awk -F":" '($2 == "" || $2 == " " || $2 == "\t") {print $0}' $file
awk -i inplace 'BEGIN{FS=OFS=":"} (NF>1) && ($2~/^[[:space:]]*$/){$2="x"} 1' file
或使用任何awk:

awk -F":" '($2 == "" || $2 == " " || $2 == "\t") {print $0}' $file
awk 'BEGIN{FS=OFS=":"} (NF>1) && ($2~/^[[:space:]]*$/){$2="x"} 1' file > tmp && mv tmp file

NF>1
的测试确保我们只对已经至少有2个字段的行进行操作,因此当输入文件中有空行时,我们不会在输出中创建类似
:x
的行。其余的希望是显而易见的。

这在计算上比我拥有的逻辑要低。因为这会对所有的因为您已将
{..}
内的操作定义为
if
。将其移出将更好地用于与部分
{..}
不匹配的行,甚至不会尝试创建,这也可以工作,但文件内的内容不会更改。awk可以直接在$file内写入结果吗(使用:x避免最后一行结果)?@MrJohn,现在添加了详细信息,您可以如何将更改保存到输入_文件本身。IMHO首先只需运行iyt并在终端上查看输出,然后执行我在帖子中添加的append命令,将更改保存到输入_文件中以确保安全。如果有任何查询,请通知我。@RavinderSingh13是的,它可以:-)非常感谢您的支持!!@RavinderSingh13我正试图给您的答案打分,但没有成功。我收到了这样一条消息:“感谢您的反馈!记录了声誉低于15的人所投的票,但不要更改公开显示的帖子分数。”您只需要
awk'$2==“||$2==“||$2==”\t“{$2=“x”}1'FS=:OFS=:/etc/passwd
很好,输出结果正常,但文件中的内容不会更改。awk是否可以直接在$file中写入结果(避免最后一行结果为:x)?
awk -F":" '($2 == "" || $2 == " " || $2 == "\t") {print $0}' $file