这是脚本的代码,我必须检查文件名是否为“pretempsc.cfg”并按原样打印其内容。 。对于任何其他文件,我只应该将以“abc disable ...”开头的行修改为“no abc ...”。
#!/bin/sh
IN_FILE=$1
OUT_FILE=$2
WhatFileIsIt() {
awk -v filename=$IN_FILE '
BEGIN {
scnode = 0;
if (filename == "pretempsc.cfg") {
scnode = 1; }
}
{
if (!scnode) {
/^abc disable/ {
print "no abc "$4"";
next;
}
print;}
}
else {print}
}
'
}
cat $IN_FILE | WhatFileIsIt | cat > $OUT_FILE
执行此脚本时,我收到以下错误:
awk: cmd. line:9: /^abc disable/ {
awk: cmd. line:9: ^ syntax error
awk: cmd. line:16: else {print}
awk: cmd. line:16: ^ syntax error
从我所能查到的情况来看,我怀疑我在操作块中使用 if 和条件操作是错误的,但我无法弄清楚到底出了什么问题。
需要注意的是:我必须在 shell 脚本中使用 awk,并且还有很多类似于 WhatFileIsIt 的其他函数对 IN_FILE 进行自己的处理。
答案1
是的,您需要将该模式匹配更改为完整if
语句:
if (/^abc disable/) {
print "no abc "$4"";
next;
}
(/pattern/
是 的简写$0 ~ /pattern/
,其中$0
包含整个输入行。)
请注意,print
there 仅打印之后输入的第四列no abc
,因此abc disable foo bar doo
变为 just no abc bar
。我不确定这是否是您想要的。
当我们这样做时,一些其他事情浮现在脑海中......如果它们太明显或与脚本的其余部分冲突,请随意忽略其中任何一个。 (希望我没有犯太多错误。)
我认为 的末尾有一个额外的右大括号print
,而且最深条件的缩进似乎有点偏离,所以稍微重写一下:
{
if (!scnode) {
if (/^abc disable/) {
print "no abc " $4;
next;
}
print;
} else {
print;
}
}
但从这里开始,似乎唯一一次做特殊的事情是当两者都!scnode
为 true 并且/^abc disable/
匹配时,在所有其他情况下只有print
.因此我们可以将条件与&&
(当然不同类型文件之间的分隔不再那么清晰。):
{
if (!scnode && /^abc disable/) {
print "no abc "$4"";
next;
} else {
print;
}
}
由于有 anext
可以缩短执行时间,finalprint
可以在没有else
子句的情况下保持不变,事实上,由于整个代码块只是一个if
,我们可以将条件放到主级别,然后执行无条件默认打印操作。
!scnode && /^abc disable/ {
print "no abc "$4"";
next;
}
1;
(当然,现在看起来可能有点太简洁了。)
另外,在 shell 脚本中,您不需要打扰猫,最好让它们睡觉并仅使用 shell 进行重定向。 (并引用 shell 变量。)
WhatFileIsIt < "$IN_FILE" > "$OUT_FILE"
该函数的名称有点令人困惑,它并没有真正回答任何“什么”问题,而是处理一个文件。也许类似ProcessFile
?
好吧,说到函数,该函数使用变量IN_FILE
,该变量不是它的本地变量。如果需要为两个不同的文件运行一个函数,可能会令人困惑。与 shell 脚本本身一样,函数也可以带参数,调用MyFunction foo
, 使$1
包含foo
在函数内部。
所以我可能会做类似的事情
ProcessFile() {
awk < "$1" -v filename="$1" '
[...]
(将输入重定向放在 awk 命令行的中间或末尾都没有关系。)
与以下产品一起使用:
ProcessFile "$IN_FILE" > "$OUT_FILE"