,所以我有一个文件,其中包含如下的块:
menuentry ... {
....
....
}
....
menuentry ... {
....
....
}
我需要在bash脚本中查看每个菜单条目的内容。我在SED方面的经验非常有限,但是通过A 详尽的搜索,我能够构建以下内容:
cat $file | sed '/^menuentry.*{/!d;x;s/^/x/;/x{1}/!{x;d};x;:a;n;/^}/!ba;q'
,我可以用我想获得nth块的任何数字替换{1}
。这样可以正常工作,但是问题是我需要迭代任意次数:
numEntries=$( egrep -c "^menuentry.*{" $file )
for i in $( seq 1 $numEntries); do
i=$( echo $i | tr -d 'n' ) # A google search indicated sed encounters problems
# when a substituted variable has a trailing return char
# Get the nth entry block of text with the sed statement from before,
# but replace with variable $i
entry=$( cat $file | sed '/^menuentry.*{/!d;x;s/^/x/;/x{$i}/!{x;d};x;:a;n;/^}/!ba;q')
# Do some stuff with $entry #
done
我尝试了围绕变量和sed语句周围的每种引号/双引号和牙套的组合以及我这样做的每一个方法,我都会遇到某种错误。正如我所说,我对SED并不了解太多,声明的Frankenstein正是我从各种Google搜索中共同完成了Mish-Mosh的内容,因此,任何帮助或解释都将不胜感激!
>tia
sed用于单个线上的简单替换,即全部替换,而操纵文本的壳循环非常缓慢且难以编写。发明SED和Shell的人也为这样的任务发明了尴尬:
awk -v RS= 'NR==3' file
将打印第三个空白分隔的文本块,如您的问题所示。这将打印每个包含字符串" foobar"的块:
awk -v RS= '/foobar/' file
,您可能想做的其他任何事情都同样微不足道。
上面将使用任何Unix框上任何外壳中的任何尴尬有效,健壮和便便。例如:
$ cat file
menuentry first {
Now is the Winter
of our discontent
}
menuentry second {
Wee sleekit cowrin
timrous beastie,
oh whit a panic's in
thy breastie.
}
menuentry third {
Twas the best of times
Twas the worst of times
Make up your damn mind
}
。
$ awk -v RS= 'NR==3' file
menuentry third {
Twas the best of times
Twas the worst of times
Make up your damn mind
}
$ awk -v RS= 'NR==2' file
menuentry second {
Wee sleekit cowrin
timrous beastie,
oh whit a panic's in
thy breastie.
}
$ awk -v RS= '/beastie/' file
menuentry second {
Wee sleekit cowrin
timrous beastie,
oh whit a panic's in
they breastie.
}
除了使用S/Old/New和SED和/或使用S,G和P以外的S/Old/New以外的其他任何事情以外1970年代发明了尴尬。
如果上述对您不起作用,请编辑您的问题以提供更多真正代表性的样本输入和预期的输出。
如何拆分此功能?
首次搜索菜单条目开始的行(出于个人原因,我在这里使用grub,而不是grub2,适应您的需求(:
entrystarts=($(sed -n '/^menuentry.*/=' /boot/grub/grub.cfg))
然后,在第二步中,从数组中选择一个启动阀,对于n-th-entry ${entrystarts[$n]}
,然后从那里继续?Afaik,入口端很容易通过单个闭合的卷曲支架检测到。
for i in ${entrystarts[@]}
do
// your code here, proof of concept (note grub/grub2):
sed -n "$i,/}/p" /boot/grub/grub.cfg
done
我看到了问题。您正在尝试使用$ i在单引号中。$我将在下面发布的$ i时将其留作$ i
'一个字符串'" $ twoStrings"'三字符串'
#!/bin/bash
#filename:grubtest.sh
numEntries=$( egrep -c "^menuentry.*{" "$1" )
i=0
while [ $i -lt $numEntries ]; do
i=$(($i+1))
# Get the nth entry block of text with the sed statement from before,
entry=$( cat "$1" | sed '/^menuentry.*{/!d;x;s/^/x/;/x{'"$i"'}/!{x;d};x;:a;n;/^}/!ba;q')
# Do some stuff with $entry #
echo $entry|cut -d' -f2
done
这是跑步时返回了我的g子./grubtest.sh/etc/grub2.cfg