我需要删除文件中匹配的特定模式和匹配的行之间的行。
在下面的代码中,我想从对象主机“ kali” {删除行到下次出现的} (而不是最后一次出现的})中的行。并在删除后删除空白。
object Host "linux" {
import "windows"
address = "linux"
groups = ["linux"]
}
object Host "kali" {
import "linux"
address = "linux"
groups = [linux ]
}
object Host "windows" {
import "linux"
address = "linux"
groups = ["windows" ]
}
这是我的代码
clear
echo -e "Enter the host to delete in config file"
cat > deletionfile.txt
clear
while read host
do
loc=`grep -il 'object.*Host.*"$host"' /home/afrith/config-file/*.conf`
sed -i "/^object.*Host.*\"$host\".*{$/,/^}$/d" $loc
done < deletionfile.txt
rm -rf deletionfile.txt
sed:没有输入文件
这是预期的输出:(当我将kali作为脚本的输入时。)
object Host "linux" {
import "windows"
address = "linux"
groups = ["linux"]
}
object Host "windows" {
import "linux"
address = "linux"
groups = ["windows" ]
}
答案 0 :(得分:6)
以下sed应该删除object Host "kali" {
和}
之间的所有行。
sed '/^object Host "kali" {$/,/^}$/d'
答案 1 :(得分:4)
尝试一下:
sed -i -Ez 's/object Host \"kali\"\s*\{[^}]*\}//g' your_file
或者,您可以尝试以下操作(也会删除空行):
sed '/object Host "kali"\s*{$/,/[^}]*}/d; /^$/d' your_file
输出将是:
object Host "linux" {
import "windows"
address = "linux"
groups = ["linux"]
}
object Host "windows" {
import "linux"
address = "linux"
groups = ["windows" ]
}
答案 2 :(得分:1)
其中一种方法是使用AWK
。您需要将记录分隔符更改为}
并运行此awk '!/kali/;BEGIN{RS="}"; ORS="}"}' < your_file
,输出就是您想要的。
我已将问题中给出的文本保存在文件test.txt
ajay@DESKTOP-PCMKVK6:~$ cat test.txt
object Host "linux" {
import "windows"
address = "linux"
groups = ["linux"]
}
object Host "kali" {
import "linux"
address = "linux"
groups = [linux ]
}
object Host "windows" {
import "linux"
address = "linux"
groups = ["windows" ]
}
现在我们需要运行此awk命令awk '!/kali/;BEGIN{RS="}"; ORS="}"}' < test.txt
ajay@DESKTOP-PCMKVK6:~$ awk '!/kali/;BEGIN{RS="}"; ORS="}"}' < test.txt
object Host "linux" {
import "windows"
address = "linux"
groups = ["linux"]
}
object Host "windows" {
import "linux"
address = "linux"
groups = ["windows" ]
}
}ajay@DESKTOP-PCMKVK6:~$
此外,您可以使用其他答案中提到的sed,也可以添加-i
选项以在同一文件中进行更改
sed -i '/^object Host "kali" {$/,/^}$/d' file_name
答案 3 :(得分:1)
通过将记录选择器设置为空,可以使gnu awk
处于块模式。
awk -v RS= -v ORS="\n\n" '/object Host "kali"/ {next} 1' file
object Host "linux" {
import "windows"
address = "linux"
groups = ["linux"]
}
object Host "windows" {
import "linux"
address = "linux"
groups = ["windows" ]
}
/object Host "kali"/ {next}
如果块包含object Host "kali"
,请跳过1
始终为true,执行默认操作,打印答案 4 :(得分:1)
这可能对您有用(GNU sed):
sed -n '/^object Host "kali" {/{:a;n;/^}/d;ba};p' file
或者:
sed '/^object Host "kali" {/{:a;N;/^}/Md;ba}' file
第一个解决方案的行为类似于grep,并选择不打印以object Host "kali" {
开头和以}
开头的行。
第二种解决方案是收集以上两种模式之间的线,然后删除这些线。
如果第一个模式匹配,第一个解决方案将更改文件,而第二个解决方案仅在两个模式都匹配时更改文件。这是因为如果要求命令n
和N
读取文件末尾之外的内容,它们将导致sed结束处理。如果设置了n
选项,-n
将安静地结束,而N
将在终止之前打印出模式空间中的所有内容。
/^}/
在行首匹配}
,在第二种解决方案中,添加了M
标志,该标志打开多行匹配,即^
和$
在换行符之后/之前匹配,此标志特定于GNU sed。 /\n}/
将具有相同的效果。如果匹配更加轻松,即匹配任何出现的}
,则/}/
就足够了。