awk 在匹配模式之前打印整行
Posted
技术标签:
【中文标题】awk 在匹配模式之前打印整行【英文标题】:awk print full line before the matched pattern 【发布时间】:2022-01-16 06:52:46 【问题描述】:重新撰写的帖子
重要 *大家早上好,谢谢你的cmets和答案,我现在不在我的电脑里,所以我可能需要稍后尝试一些答案,我会将对我有用的答案标记为正确的解决方案。如果我在这篇文章中的措辞不是最好的,我深表歉意,我昨晚筋疲力尽,在发布这篇文章之前我什至没有检查我的措辞。 *
我会更好地澄清我的问题:
所以我有一个脚本,我们将其称为./run.sh
,在该脚本内部我有一个变量,称为SCRIPT=DIR
这个变量运行一个命令
cd -- "$( dirname -- "$BASH_SOURCE[0]" )" &> /dev/null && pwd
所以完整的变量看起来像:
SCRIPT_DIR="$( cd -- "$( dirname -- "$BASH_SOURCE[0]" )" &> /dev/null && pwd )"
然后在该变量下面我有一个打印变量 SCRIPT_DIR 的回显
echo $SCRIPT_DIR
当我运行脚本./run.sh
时,我打印了以下字符串
/home/vMX-ENV/vMX-21.1R1/scripts/boot/
我的问题是,通过使用 awk 从给定字符串中删除文本,我想删除 scripts/boot/
所以,我正在考虑匹配 scripts/
之类的模式并打印 scripts/
之前的每一行。通过仅将 scripts/
与 awk 匹配,我希望能够得到如下结果:
/home/vMX-ENV/vMX-21.1R1/
我找了很长时间,但找不到类似的东西并没有答案,我尝试了其他人在另一篇文章中给出的命令,该命令打印了匹配模式之前的内容,我试图修改该命令以适合我的脚本,但没有成功。希望这更好理解!
再次抱歉
---- 上一篇文章 ---- 请忽略 所以我知道有很多帖子试图解决这个问题;但是,我还没有成功地做到这一点!所以我有一个脚本,它告诉我我的 bash 脚本所在的目录,这是我从另一篇文章中获取的:
#SCRIPT_DIR="$( cd -- "$( dirname -- "$BASH_SOURCE[0]" )" &> /dev/null && pwd )"
/home/vMX-ENV/vMX-21.1R1/scripts/boot
我正在尝试从结果中删除 /scripts/boot 目录,因此它最终会是:
/home/vMX-ENV/vMX-21.1R1/
我正在尝试使用awk
作为我的解决方案,我知道还有其他命令,例如 grep 或 perl,但我宁愿使用 awk 只是为了保持一致。有谁知道我怎样才能做到这一点?我有过很多次不成功的尝试
有人在另一个帖子上建议使用
awk '/foo/if (a && a !~ /foo/) print a; print a=$0' file
但我无法让它工作。此外,我对 bash 没有太多经验,所以我想不出解决它的方法。有什么帮助吗?
【问题讨论】:
不确定我是否理解您发布的两行“脚本”...您是说SCRIPT_DIR
变量包含字符串/home/vMX-ENV/vMX-21.1R1/scripts/boot
?还是字符串/home/vMX-ENV/vMX-21.1R1/scripts/boot
是脚本中的硬编码行(如果是这样,#SCRIPT_DIR=
行的意义是什么)?这与主题print full line before the matched pattern
有什么关系...什么“模式”和什么“全线”?
我无法想象你发布的那个 awk 脚本可能与你描述的问题和你给出的例子有什么关系,它完全不相关(但它可能对上述问题有意义在你的主题awk print full line before the matched pattern
),所以这让我觉得你在这里描述的问题可能不够好。另外,您是字面上想从原始字符串的末尾删除字符串/scripts/boot
,还是真的想删除最后两个路径段,无论它们的值如何?
您说 I rather use awk just to keep it consistent
但您发布的代码中没有 awk - 与什么一致?
如果您从/home/vMX-ENV/vMX-21.1R1/scripts/boot
中删除/scripts/boot
,结果是/home/vMX-ENV/vMX-21.1R1
,而不是/home/vMX-ENV/vMX-21.1R1/
,请edit 您的问题是修复您要删除的字符串或预期的结果删除字符串。
对不起,我在深夜写了这条消息,我累了,我会澄清一下,我会更好!所以我有一个脚本有一个名为 SCRIPT_DIR 的变量,当我运行该命令时,我可以 echo $SCRIPT_DIR 打印出我的脚本所在的目录。当然 SCRIPT_DIR 是变量!对困惑感到抱歉。此外,如果有意义的话,我正在尝试使用 awk 从我的 echo 中删除字符串 /scripts/boot/
【参考方案1】:
您的问题不清楚,但也许这就是您要尝试做的,即只需使用您的脚本所在目录上方 2 级目录的路径填充 SCRIPT_DIR?
SCRIPT_DIR="$( cd -- "$( dirname -- "$BASH_SOURCE[0]" )/../.." &> /dev/null && pwd )"
【讨论】:
对不起,我已经发布了一个更好的解释帖子,希望更有意义!谢谢你的回答,我今天到办公室后会试一试,我会告诉你的!【参考方案2】:这是一个删除尾随部分的 AWK 命令:
$ echo /home/vMX-ENV/vMX-21.1R1/scripts/boot | awk 'match($0, "/scripts/boot$") print substr($0, 1, RSTART - 1) '
/home/vMX-ENV/vMX-21.1R1
【讨论】:
awk 'sub("/scripts/boot$","")
会更简洁高效。
@EdMorton 确实!【参考方案3】:
您可以使用sed
,而不是使用awk
,如下所示:
echo /home/vMX-ENV/vMX-21.1R1/scripts/boot | sed 's/scripts\/boot$//'
这将为您提供输出:
/home/vMX-ENV/vMX-21.1R1/
【讨论】:
当您在正则表达式或替换字符串中有/
s 时,您应该使用/
以外的其他字符作为分隔符,这样您就不需要转义那些/
s,例如sed 's:/scripts/boot$::'
.
@EdMorton:您的解决方案sed 's:/scripts/boot$::'
将给出/home/vMX-ENV/vMX-21.1R1
作为输出,没有尾随/
,这不是PO 要求的。他想要/home/vMX-ENV/vMX-21.1R1/
作为输出。见上文。
显然,如果您不想包含领先的 /
,那就不要,这不是我评论的重点,但他们也说 I am trying to remove the /scripts/boot
所以请选择要求,因此my comment under the question.
@EdMorton:我显然也同意您关于更改分隔符的评论。我只是选择了转义 /
,以便让作为 PO 的新用户更容易理解我的 sed
命令。以上是关于awk 在匹配模式之前打印整行的主要内容,如果未能解决你的问题,请参考以下文章