Awk sed匹配模式并插入换行符,后跟替换文本

Awk sed匹配模式并插入换行符,后跟替换文本,awk,sed,newline,text-processing,Awk,Sed,Newline,Text Processing,假设我的输入文件es服务有以下几行: 如果上述文件中不存在模式key2=value2,则将其添加到key1=value1之后 因此,该文件现在应该具有: 为了实现这一目标,我提出了以下建议: if ! grep -qxF 'key2=value2' es-service; then sed -i "/key1/a \n# Comment 2\nkey2=value2" es-service fi 问题是/a没有插入新行之后的第一行\n。因此,我最终得出以下结论: key1=value1 n

假设我的输入文件es服务有以下几行:

如果上述文件中不存在模式key2=value2,则将其添加到key1=value1之后

因此,该文件现在应该具有:

为了实现这一目标,我提出了以下建议:

if ! grep -qxF 'key2=value2' es-service;
  then sed -i "/key1/a \n# Comment 2\nkey2=value2" es-service
fi
问题是/a没有插入新行之后的第一行\n。因此,我最终得出以下结论:

key1=value1
n# Comment 2
key2=value2
而不是

key1=value1

# Comment 2
key2=value2
编辑: 我最终解决了这个问题,添加了一个sed来匹配注释2,并使用选项I在它前面添加了一个换行符

全部在awk中使用循环

awk '/key2=/ {f=1} /key1=/ {n=NR} {a[NR]=$0} END {for(i=1;i<=NR;i++) {print a[i];if(i==n && !f) print "\n# Comment 2\nkey2=value2"}}' file
# Comment 1
key1=value1

# Comment 2
key2=value2

# Comment 3
key3=value3
/key2=/{f=1}如果找到key2=则设置标志f以防止双重插入。 /key1=/{n=NR}如果找到key1,则将行号存储在n中 a[NR]=$0存储阵列a中的所有行 运行文件后结束,执行以下操作: fori=1;i全部在awk中使用循环

awk '/key2=/ {f=1} /key1=/ {n=NR} {a[NR]=$0} END {for(i=1;i<=NR;i++) {print a[i];if(i==n && !f) print "\n# Comment 2\nkey2=value2"}}' file
# Comment 1
key1=value1

# Comment 2
key2=value2

# Comment 3
key3=value3
/key2=/{f=1}如果找到key2=则设置标志f以防止双重插入。 /key1=/{n=NR}如果找到key1,则将行号存储在n中 a[NR]=$0存储阵列a中的所有行 运行文件后结束,执行以下操作: fori=1;ignu-awk无环解

awk -v RS= -v ORS='\n\n' 'NR>1 && a~/key1/ && !/key2/ {print "# Comment 2\nkey2=value2"} 1; {a=$0}' file
# Comment 1
key1=value1

# Comment 2
key2=value2

# Comment 3
key3=value3
-v RS=-v ORS='\n\n'将记录选择器设置为nothing,并将记录选择器输出到两个新行 NR>1&&a~/key1/&/key2/跳过第一个块并测试上一个块是否包含key1,当前行是否不包含key2,然后 打印注释2\nkey2=value2添加新块 1.始终为true,因此它将打印所有行。 a=$0将行存储在变量a中,用于下一行的测试 一种无环路的gnu-awk解决方案

awk -v RS= -v ORS='\n\n' 'NR>1 && a~/key1/ && !/key2/ {print "# Comment 2\nkey2=value2"} 1; {a=$0}' file
# Comment 1
key1=value1

# Comment 2
key2=value2

# Comment 3
key3=value3
-v RS=-v ORS='\n\n'将记录选择器设置为nothing,并将记录选择器输出到两个新行 NR>1&&a~/key1/&/key2/跳过第一个块并测试上一个块是否包含key1,当前行是否不包含key2,然后 打印注释2\nkey2=value2添加新块 1.始终为true,因此它将打印所有行。 a=$0将行存储在变量a中,用于下一行的测试
请尝试以下操作,如果键在序列中不连续,此代码将处理任何缺少的键,并使用注释编号添加它们

awk '
BEGIN{
  FS="="
}
!NF{
  print
  next
}
/^# Comment/{
  val=$0
  next
}
/^key/{
  first_col=$1
  sub(/[a-zA-Z]+/,"",first_col)
  while(first_col!=prev+1){
     prev++
     print "# Comment "prev ORS "key"prev"=value"prev ORS
  }
  prev=first_col
  print val ORS $0
}
'  Input_file

请尝试以下操作,如果键在序列中不连续,此代码将处理任何缺少的键,并使用注释编号添加它们

awk '
BEGIN{
  FS="="
}
!NF{
  print
  next
}
/^# Comment/{
  val=$0
  next
}
/^key/{
  first_col=$1
  sub(/[a-zA-Z]+/,"",first_col)
  while(first_col!=prev+1){
     prev++
     print "# Comment "prev ORS "key"prev"=value"prev ORS
  }
  prev=first_col
  print val ORS $0
}
'  Input_file
a和我很难在线

因此,对于匹配数据,只需使用s///替换和&即可。换言之,在。。。是附加的字符串

sed-i'/key1/s/*/&\n注释2\nkey2=value2/'es服务

或者:

您可以使用s///e构造一个shell命令来生成要放入流中的输出

sed-i'/key1/s/*/printf&\n Comment 2\nkey2=value2\n/e'es服务

因此,我将用printf&\n替换。*,后跟要插入的内容

然后执行printf并将输出粘贴到流中。我原以为e只是GNU使用的,但它在-posix中对我有效。

a和我很难内联

因此,对于匹配数据,只需使用s///替换和&即可。换句话说,s/*/&\n.../其中。。。是附加的字符串

sed-i'/key1/s/*/&\n注释2\nkey2=value2/'es服务

或者:

您可以使用s///e构造一个shell命令来生成要放入流中的输出

sed-i'/key1/s/*/printf&\n Comment 2\nkey2=value2\n/e'es服务

因此,我将用printf&\n替换。*,后跟要插入的内容


然后执行printf并将输出粘贴到流中。我原以为e只是GNU使用的,但它在-posix中对我有效。

@SandeepKanabar添加了信息。但请注意,如果文件太大,它可能会因为将所有行存储在一个数组中而减慢速度。同意这就是我们希望使用sed的原因。@SandeepKanabar如果key2需要位于key1之后,而不是文件中的其他位置,它可以在没有循环的情况下停止。但是如果是随机位置,您需要先测试整个文件。@SandeepKanabar添加了信息。但请注意,如果文件太大,它可能会因为将所有行存储在一个数组中而减慢速度。同意这就是我们希望使用sed的原因。@SandeepKanabar如果key2需要位于key1之后,而不是文件中的其他位置,它可以在没有循环的情况下停止。但如果是随机位置,您需要先测试整个文件。@Sandeep Kanabar,我尝试了通用方法,您能检查一下并告诉我这是否对您有帮助吗?@Sandeep Kanabar,我尝试了通用方法,您能检查一下并告诉我这是否对您有帮助吗?