从文件中删除以#开头的所有行

266

文件中所有以 # 开头的注释行都需要删除。如何只删除这些行而保留其他包含# 的行,但该符号不在行首?


1
它是否必须遵循常见约定,即#blah \<nl>blah被视为单个“逻辑行”,因为反斜杠转义了换行符? - sarnold
@sarnold:除了make之外,哪些实用程序使用“反斜杠拼接行以结束注释”?Shell(已测试bash和ksh)不会。C和C++在处理预处理器指令的其他处理之前确实处理换行符拼接,但它们是指令而不是注释。 - Jonathan Leffler
@Jonathan:太棒了。我一直以为常见的\<nl>转义也适用于注释。但是哇,我错了。我还没有找到另一个例子... :) 谢谢! - sarnold
10个回答

439

这可以使用一个 sed 单行命令 实现:

sed '/^#/d'

这段话的意思是,“查找以#开头的所有行并删除它们,保留其他内容。”


13
去掉以 # 开头的行。 - kev
118
对于像我这样的Linux新手:sed '/^#/ d' < inputFile.txt > outputFile.txt 的意思是从 inputFile.txt 文件中删除以 # 开头的行,并将结果输出到 outputFile.txt 文件中。 - Neil McGuigan
69
最简短的版本为:sed -i '/^#/d' 文件路径。该命令的作用是删除文件路径中以井号(#)开头的行。 - lesderid
22
在Mac系统上,执行sed -i '' '/^#/d' filepath命令(因为必须使用-i后缀)。该命令的作用是删除文件中以#开头的行。 - paulcm
1
@Viesturs 试试这个:awk '/^#/ && !first { first=1 ; next } { print $0}' - Raymond Hettinger
显示剩余7条评论

76

我有点惊讶,没有人提出最明显的解决方案:

grep -v '^#' filename

这个解决了所述的问题。

但请注意,一个常见的约定是从 # 到行末的所有内容都被视为注释:

sed 's/#.*$//' filename

虽然这可能并不适用于你的情况,但是它把例如字符串字面量中的#字符视为注释的开头(这可能与你的情况有关),并留下空行。

以任意空格开头后跟着#的行也可能被视为注释:

grep -v '^ *#' filename

如果空格只有空格,或者

grep -v '^[  ]#' filename

其中两个空格实际上是一个空格后面跟着一个文本制表符(键入“控制键-v”和“tab”)。

对于所有这些命令,省略文件名参数以从标准输入读取(例如作为管道的一部分)。


我已经添加了一个新答案,它是在这个答案的基础上构建的。 - Asclepius
我在Windows上使用grep时遇到了麻烦。解决方法是将'替换为",例如grep -v "^#" filename - Serg

22
雷蒙德提出的解决方案的反面:
sed -n '/^#/!p'

"不要打印任何内容,除非该行不以 # 开头"


好的,这里有什么优势? - lacostenycoder
1
@lacostenycoder 这个选项与其他提出的选项差不多,足以值得一提。 - ata

14

您可以直接使用 编辑器 编辑您的文件。

sed -i '/^#/ d'

如果您想删除以某些空格开头的注释行,可以使用:
sed -i '/^\s*#/ d'

通常情况下,如果脚本的第一行是sha-bang,您希望保留它,因此 sed 不应删除以#!开头的行。此外,它还应删除仅包含哈希但没有文本的行。将所有这些放在一起:

sed -i '/^\s*\(#[^!].*\|#$\)/d'

为了与所有sed变体兼容,您需要将备份扩展名添加到-i选项:

为了与所有sed变体兼容,您需要在-i选项中添加备份扩展名:

sed -i.bak '/^\s*#/ d' $file
rm -Rf $file.bak

1
加1给那个空间。 - deepaksingh pawar

8

假设您的 egrep 支持该语法;旧版本可能不支持。 - Keith Thompson

8
您可以使用以下内容来解决awk问题 -
awk '/^#/ {sub(/#.*/,"");getline;}1' inputfile

2

你可能也想删除空行

sed -E '/(^$|^#)/d' inputfile

或者使用 grep -v '^ *\(#.*\|\)$' 命令来删除只包含空格或空格前有注释的行。 - techno

1

如果你想从文件中以特定单词开头的位置开始删除,那么可以执行以下操作:

grep -v '^pattern' currentFileName > newFileName && mv newFileName currentFileName

因此,我们已经删除了所有以某种模式开头的行,将内容写入新文件,然后将内容复制回源/当前文件。


0

删除所有空行以及在任何空格后以#开头的所有行:

sed -E '/^$|^\s*#/d' inputfile

例如,查看以下已删除的3行(包括行号!):
1. # first comment
2.
3.         # second comment

在测试了上述命令后,您可以使用选项-i直接编辑输入文件。

就这样!


-3

这里是一个循环遍历所有带有某个扩展名的文件的代码:

ll -ltr *.filename_extension > list.lst

for i in $(cat list.lst | awk '{ print $8 }') # validate if it is the 8 column on ls 
do
    echo $i
    sed -i '/^#/d' $i
done

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接