如何从文件中删除所有评论?

Que*_*ark 33 grep sed awk shell-script text-processing

我有一个包含评论的文件:

foo
bar
stuff
#Do not show this...
morestuff
evenmorestuff#Or this
Run Code Online (Sandbox Code Playgroud)

我想打印文件而不包含任何注释:

foo
bar
stuff
morestuff
evenmorestuff
Run Code Online (Sandbox Code Playgroud)

有很多应用程序在这方面会有所帮助。有什么好的方法可以做到?

jim*_*mij 53

删除所有注释的一种方法是使用grepwith-o选项:

grep -o '^[^#]*' file
Run Code Online (Sandbox Code Playgroud)

在哪里

  • -o: 只打印该行的匹配部分
  • 第一^:行首
  • [^#]*: 除#重复零次或多次以外的任何字符

请注意,空行也将被删除,但只有空格的行将保留。

  • 我会使用`grep -v '^#' file > newfilewithoutcomments` (5认同)
  • 应该注意,这不是 shell 脚本的通用方法,例如行`somvar='I am a long complex string ## with special characters' # and I am a comment` 将无法正确处理。 (3认同)
  • 这是如何获得 40 票并被选为最佳答案的???它甚至不处理简单的情况`print "#tag" # Print a hashtag.`。 (3认同)
  • 像大多数答案一样,这甚至会杀死 shebang! (3认同)

Jos*_* R. 41

我相信在这方面sed可以做得比grep. 像这样的东西:

sed '/^[[:blank:]]*#/d;s/#.*//' your_file
Run Code Online (Sandbox Code Playgroud)

解释

  • sed默认情况下,将逐行查看您的文件,并在可能应用引号中的转换后打印每一行。(sed '' your_file将只打印所有行不变)。
  • 这里我们给出sed了在每一行执行的两个命令(它们用分号分隔)。
  • 第一个命令说:/^[[:blank:]]*#/d。在英语中,这意味着如果该行与开头的哈希匹配(前面有任意数量的前导空格),则删除该行(不会打印)。
  • 第二个命令是:s/#.*//。也就是说,在英语中,将哈希标记后跟尽可能多的东西(直到行尾)替换为空(空是最后两个之间的空白//)。
  • 总之,这将贯穿您的文件,删除完全由注释组成的行,之后剩下的任何行都将删除注释。

  • 它还将删除在哈希 * 字符串内 * 之后找到的任何内容,不是吗?例如`mystring="Hello I am a #hash"` 将变成`mystring="Hello I am a"` (5认同)
  • 一个小的增强... `sed '/^[[:blank:]]*#/d;s/[[:blank:]]*#.*//' your_file`。您的原始命令在一行中留下了一些尾随空白。我的增强也摆脱了这些。 (3认同)

Edu*_*omo 6

输入示例

cat example.sh
Run Code Online (Sandbox Code Playgroud)
cat example.sh
Run Code Online (Sandbox Code Playgroud)

删除评论

#!/bin/bash
# example script

echo "# test";# echo "# test"

# check the first parameter
if [ "$1" = "#" ]; then 
  # test couple of different cases
  echo "#"; # output # character 
  echo '\#'; # output # character '#' for test purpose
  echo \#\#\#; # comment # comment # comment '# comment'
  echo \#
  echo \#;
  echo \#; # comment
fi
# end of the script
Run Code Online (Sandbox Code Playgroud)

结果

cat example.sh
Run Code Online (Sandbox Code Playgroud)
sed -e '1{/^#!/ {p}}; /^[\t\ ]*#/d;/\.*#.*/ {/[\x22\x27].*#.*[\x22\x27]/ !{:regular_loop s/\(.*\)*[^\]#.*/\1/;t regular_loop}; /[\x22\x27].*#.*[\x22\x27]/ {:special_loop s/\([\x22\x27].*#.*[^\x22\x27]\)#.*/\1/;t special_loop}; /\\#/ {:second_special_loop s/\(.*\\#.*[^\]\)#.*/\1/;t second_special_loop}}' example.sh
Run Code Online (Sandbox Code Playgroud)

阅读源代码的工作原理:https://blog.sleeplessbeastie.eu/2012/11/07/how-to-remove-comments-from-a-shell-script/


小智 5

正如其他人指出的那样,如果脚本的任何部分看起来像注释但实际上不是,则 sed 和其他基于文本的工具将无法正常工作。例如,您可以在字符串中找到 # 或相当常见的$#and ${#param}

我编写了一个名为shfmt的 shell 格式化程序,它具有缩小代码的功能。这包括删除评论等:

$ cat foo.sh
echo $# # inline comment
# lone comment
echo '# this is not a comment'
[mvdan@carbon:12] [0] [/home/mvdan]
$ shfmt -mn foo.sh
echo $#
echo '# this is not a comment'
Run Code Online (Sandbox Code Playgroud)

解析器和打印机是 Go 包,因此如果您想要自定义解决方案,编写一个 20 行的 Go 程序来以您想要的确切方式删除注释应该相当容易。