如何“分类”文件并删除注释行?


29

我想知道是否有一种方法可以cat归档php.ini并删除所有以;

例如,如果文件包含以下内容:

;   - Show all errors, except for notices
;
;error_reporting = E_ALL & ~E_NOTICE
;
;   - Show only errors
;
;error_reporting = E_COMPILE_ERROR|E_ERROR|E_CORE_ERROR
;
;   - Show all errors except for notices
;
error_reporting  =  E_ALL & ~E_NOTICE

然后我运行了正确的命令cat | {remove comments command},那么最终结果是:

error_reporting  =  E_ALL & ~E_NOTICE

-我认为cat会做到这一点的最好办法,但实际上,我细使用其他实用程序一样的答案awksedegrep,等。


那类似的东西error_reporting = E_ALL & E_NOTICE ; Show all errors, except for notices呢?在这种情况下也应删除评论吗?
的CVn

@MichaelKjörling-我真的很好,只是删除注释开头的行
cwd

1
cat是串联文件的工具。grep是根据图案过滤线的工具。sed并且awk还可以修改这些行。
斯特凡Chazelas

Answers:



25

您不需要通过grep传递文件,grep将文件名作为命令行参数。

grep -v '^#' file1 file2 file3

将打印除以#char开头的行以外的所有行。您可以将注释字符更改为所需的任何字符。

如果您有多个注释字符(假设在一行的开头)

egrep -v '^(;|#|//)' filelist

2
我做过的另一个总是与我在一起的是grep '^[^;]' filename。我不能说它的便携性!
朱迪·C

@JodieC,这是可移植的,但也删除了空行(通常需要这样做)。的标准等效项egrepgrep -E。你也可以使用grep -ve '^[;#]' -e '^//'
斯特凡Chazelas

9

egrep可以节省您对的使用cat。换句话说,创建更少的进程(egrepvs cat+ egrep)并使用更少的缓冲区(从from categrepvs的管道)。

cat如果只想将文件传递给可以自行读取的命令,通常最好限制使用。

如此说来,即使用空格或制表符缩进,以下命令也将删除注释:

egrep -v'^ [[::空白:]] *;' file.ini

有趣的是,您将较新的[[ 字符类 ]]正则表达式格式与egrep至少十年左右已弃用的命令结合使用。
mikeserv

有趣的是…… gnu.org/software/grep/manual/html_node/ …上的当前文档包括POSIX类。
杰克·瓦西

7
egrep -v '^;|^$' $file

这将排除以';'开头的行和空行。

在regex中,^表示行的开头和行$的结尾,因此^$指定其中行字符的开头和行字符的结尾彼此紧邻的行。


因此,如果我没有看错,可以删除注释行,但也可以删除空白行?
cwd

1
@cwd是的。我不确定他为什么要同时包括两者,但是如果您只想删除注释行,请使用egrep -v '^;'
Michael Mrozek

4
egrep也喜欢文件(使用较少的进程和缓冲区),还有一点好处是也可以删除缩进的注释:egrep -v '^[[:blank:]]*;' file.ini
nrolans 2011年

10
我们需要一个“无用的猫”徽章。
Simon Richter

@nrolans-看起来很受欢迎,为什么不回答呢?
cwd

2

一个简单awk的一行awk '/^;/{next}1' input_file应该做的伎俩。

[jaypal:~/Temp] cat file
;   - Show all errors, except for notices
;
;error_reporting = E_ALL & ~E_NOTICE
;
;   - Show only errors
;
;error_reporting = E_COMPILE_ERROR|E_ERROR|E_CORE_ERROR
;
;   - Show all errors except for notices
;
error_reporting  =  E_ALL & ~E_NOTICE

[jaypal:~/Temp] awk '/^;/{next}1' file
error_reporting  =  E_ALL & ~E_NOTICE
[jaypal:~/Temp] 

3
正确,但冗长。仅仅awk '!/^;/' input_file是不够的。
manatwork 2011年

2

和Jaypal一样,我也很可能会awk用于这些目的。更糟糕的是,出于以下目的,Perl有时非常方便:

cat data.txt | perl -lne "print unless /^;/"

与awk相比,Perl正则表达式更强大,有时您可能需要它们。


perl +1,尽管cat和-l都是多余的,所以更简单的调用是perl -ne 'print unless /^;/' data.txt
Simon Whitaker

@Simone Whitaker,是的,您是对的-以我的写作方式写它只是一个习惯,值得一提。
shabunc 2011年

1
当然可以 实际上,cat如果您将其视为更通用的“在STDOUT上生成文本的任何内容”的代理,则在这些示例中我认为效果很好。自从切成薄片以来,Unix管道是最好的东西,恕我直言。:)
西蒙·惠特克

2

详细说明@shabunc的答案,它使用Perl剥离注释(包括内联注释),然后打印除空格以外的任何行。

$ perl -ne 's/;.*//; print if /\S/' data.txt

说明:

  • s/;.*//使用替换运算符(s/<regex>/<replacement>/)替换分号的实例以及空行中一行后的所有内容。
  • print if /\S/如果匹配regexp \S,则打印该行,regexp 是与所有非空白字符匹配的字符类

1

这是我使用的一个,只需替换为';' 带有注释字符(例如,许多UNIX服务配置文件为'#'):

grep -Ev '^[[:space:]]*;|^$' chan_dahdi.conf.sample | sed 's/;.*$//'

这样就消除了所有全行注释(即使它们有前导的空格),也消除了所有以非注释行结尾的注释,并且还从输出中简洁地删除了空白行。如果没有管道,这可能是可能的(我的sed-或awk-fu不太好),但是对我来说很容易理解(记住),我想我会在这里发布它。


1

示例仅显示行+不显示新行或空行:

$ egrep -v '^(;|#|//)' /etc/ssh/sshd_config | tr '\n' ' '

 Protocol 2    SyslogFacility AUTHPRIV      PasswordAuthentication yes  ChallengeResponseAuthentication no   GSSAPIAuthentication yes GSSAPICleanupCredentials yes  UsePAM yes  AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE AcceptEnv XMODIFIERS  X11Forwarding yes   Subsystem sftp    /usr/libexec/openssh/sftp-server 

要么

$ egrep -v '^(;|#|//|$)' /etc/ssh/sshd_config    

Protocol 2
SyslogFacility AUTHPRIV
PasswordAuthentication yes
ChallengeResponseAuthentication no
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes
UsePAM yes
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
X11Forwarding yes
Subsystem   sftp    /usr/libexec/openssh/sftp-server

2
采用egrep长弃用。grep -E是您在此处查找的命令。
mikeserv

0
egrep -v ^'(#|$)' file.txt

删除file.txt中的所有注释和空行


2
您应该考虑使用更多有关未启动的信息(例如,您使用的正则表达式的功能)来扩展答案。
HalosGhost

egrep已折旧。使用grep -Ev代替。
Yokai


0

您可以使用以下命令在新文件中保存行,不包括空行和以#开头的行

cat <file to be read> | egrep -v '^#|^$' > <file to be written at>


没用的cat管道,egrep已贬值,将其替换grep -E为扩展表达式或just grep -v
Yokai
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.