我正在尝试使用 awk 过滤脚本中的文件路径,以便它忽略正则表达式中的任何内容:
FILTERED_FILE=$(echo $File | awk -F / "{(for(i=NF; i>=0; i--) {if $(i!~^(NewConfig|Old|old|backup|Backup|Servers)$ print $i}}") ;
我基本上试图逐个字段迭代并提取文件路径中不包含任何这些关键字的第一个字段。因此,如果文件路径是,例如:
/etc/Backup/Servers/blah/Old
我希望变量$FILTERED_FILE
是blah
.
这精确的该行在不同的脚本中按预期工作,但现在 awk 变量 ($i) 仍为空。我是 awk 的初学者,所以我肯定会错过一些东西 - 我将不胜感激关于在哪里寻找的建议。我不认为这一行依赖于脚本中的任何其他行(同样,这在我改编的前一个脚本中有效),但如果有必要,我会上传更多内容。我也不致力于 awk - 如果你能想到更好的工具(grep、sed 等),它也一样好。
谢谢你!
答案1
我认为您的 shell 以及您的awk
代码存在几个问题。
首先,始终将awk
代码放在单引号中,如awk '<commands>'
.否则,可能会发生奇怪的效果,例如壳解释$<...>
声明。
其次,您的语法在几个地方看起来错误:
- 你说正在寻找第一的字段不匹配,但似乎正在寻找最后的一?但是,您的代码会打印全部其他不匹配的字段也是如此,因为在找到第一个匹配项后您不会跳出循环。
- RegExp 比较应该类似于
if ($i !~ /^( .... )$/) { ... }
if
在您的示例代码中,缺少语句的右括号。
第三,您还应该在 shell 脚本中用双引号替换命令。
修改后的 awk
代码将是
awk -F '/' '{for (i=NF; i>0; i--) {if ($i !~ /^(NewConfig|[Oo]ld|[Bb]ackup|Servers)$/) {print $i; exit}}}'
要从脚本中调用它,请使用
Filtered_File="$( echo "$File" | awk -F '/' ' .... ')"
请注意,由于结构的原因,最后一部分实际上只能在脚本内工作!~
。在命令行上完成时,至少bash
会在启动用于命令替换的子 shell 之前尝试执行命令历史记录扩展,这会导致错误消息。