我尝试使用 bash 在 oracle linux 8.6 中使用模式取消注释文件中的特定行。某些行上的前导空格未被删除。我尝试使用 sed 和 grep 取消注释注释行以匹配模式。我需要精确匹配输出中的两个数字。文件中每列(共 2 列)有一个单词,每个单词都有数字。
例如: column1:pd 19 _ORA column2:svg 38。
我需要取消注释完全匹配 19 和 38 的行,但不包含 190、1900 或 019 等,例如,
#pd19_ORA svg37
#pd199_ORA svg388
代码:
sed -n '/\<19\>/,+1p' cmfile|grep '38'|sed -i '/38/s/^#//g' cmfile
文件内容:
#pd19_ORA svg38
#pd19_ORA sil38
#pd29_ORA sil37
使用 sed 和 inplace 后第一行仍然被注释,但第二行的注释被删除。
输出:
#pd19_ORA svg38
pd19_ORA sil38
#pd29_ORA sil37
如何删除第一行带有前导空格的注释而不删除前导空格?
预期输出:
pd19_ORA svg38
pd19_ORA sil38
#pd29_ORA sil37
您可以尝试
awk
使用这样的命令来完成工作。如果您需要特定的字符串19
和38
特定位置,则应在问题中提及它:此命令搜索带有 的行
19
并38
删除#
符号。然后打印该行(无论它是否匹配和编辑)如果您想确定
#
该行中是否有第一个非空白符号,您可以像这样修改脚本:这里是更改后的脚本,用于搜索特定字符串并匹配所需的数字:
我认为您希望
#
从包含数字的所有行中删除前导字符19
,同时保留任何前导空格这将搜索包含
19
(但两侧没有数字,例如019
或193
)的行,因为我无法\<19\>
匹配此处的任何行。如果您想要包含以下内容的行
19
,38
则只需扩展初始行匹配:在这两种情况下,对于所有匹配的行,我们都会捕获
#
字符前面的任何前导空格,以便将其添加回输出中。最后,作为另一种变体,
sed -i ...
可用于更新看似到位的文件假设您想要取消注释包含 38 的行,并且该行位于包含单词分隔¹的行之后,
19
正如您的尝试建议的那样,您可能需要执行以下操作:在您的:
该
sed -i '/38/s/^#//g' cmfile
命令不会读取其输入,它只会在适当位置进行编辑,删除包含的任何行上的cmfile
前导(顺便说一句,是多余的,因为只能有一次替换)。#
38
g
因此这
sed -n '/\<19\>/,+1p' cmfile|grep '38'
是毫无意义的,因为没有任何东西读取它的输出。另请注意,所有的
-i
、都是非标准 GNU 扩展²,但命令可以在任何系统上运行³+1
。\<\>
perl
编辑
根据您更新后的要求,您想要取消注释第一个字段包含 19 且第二个字段包含 38(它们本身没有被其他数字包围)的行:
这里使用
-a
wk 模式,字段在数组中可用@F
,或者,如果两侧可能有空格#
,导致第一个字段成为第二个字段,请使用正则表达式进行整行匹配:我们所拥有的(详情请参阅
perldoc perlrun
和perldoc perlop
)perldoc perlre
:-p
:sed
模式,其中-e
对每行输入评估 xpression。-i
:i
n 位编辑s/regexp/replacement/
:s
用 替换正则表达式的第一个匹配项replacement
。\s
:任何空白字符,\S
用于非空白。<atom>*
:前一个原子重复任意次数(包括 0 次),尽可能多\K
:K
保留左侧的内容,或者 IOW 重置最终将被替换的比赛的开始。(?=...)
:积极前瞻,或 IOW“只要接下来的内容匹配...”(?<!...)
:负面后视,或 IOW“假设前面的内容不匹配...”(?!...)
:负面前瞻\d
:任意十进制数字字符。如果没有-C
(对于 Unicode 模式),则限制为 0123456789。¹ 无论如何,
19
inpd19_ORA
不是以单词分隔的,因为d
和_
都是单词字符;如果您想要匹配前面19
和后面都没有十进制数字的,则可以使用(?<!\d)19(?!\d)
而不是\b19\b
(perl 中相当于ex
'\<19\>
)。² 嗯,严格来说,
\<\>
起源于ex
/vi
,而不是 GNUsed
并且是由 GNU从和-i
复制而来。sed
perl
,+1
ed
³ 不过,您需要 perl 5.10.0(自 2007 版)或更新版本
\K
(以K
保留其左侧内容)。在将使用旧版本的系统上perl
,您可以将其替换s/^\s*\K#//
为s/^(\s*)#/$1/
。^#
仅匹配#
行首。允许注释前有空格的另一种方法是^[ \t]*#
因此,这一行应该有效: