Awk sed匹配模式并插入换行符,后跟替换文本
假设我的输入文件es服务有以下几行: 如果上述文件中不存在模式key2=value2,则将其添加到key1=value1之后 因此,该文件现在应该具有: 为了实现这一目标,我提出了以下建议: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
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,我尝试了通用方法,您能检查一下并告诉我这是否对您有帮助吗?