【问题标题】:How to print a file, excluding comments and blank lines, using grep/sed?如何使用 grep/sed 打印文件,不包括注释和空行?
【发布时间】:2013-06-27 21:20:40
【问题描述】:

我想打印一个包含一系列 cmets 的文件,例如:

    </Directory>
    ErrorLog ${APACHE_LOG_DIR}/error.log
    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn
    CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined
    #   SSL Engine Switch:

本质上,该文件包含多个缩进级别,其中注释以# 符号开头。

grep 应该删除空白行,以及文本前有井号的行(暗示这些是 cmets)。

我知道可以通过以下方式删除空行:grep -v '^$'

但是,如何删除带有前导空格的行,然后是 # 符号,并仅打印带有实际代码的行?我想在 bash 中执行此操作,使用 grep 和/或 sed。

【问题讨论】:

    标签: regex awk sed grep


    【解决方案1】:

    sed 可能比grep 更容易:

    sed -e '/^[[:space:]]*$/d' -e '/^[[:space:]]*#/d' test.in
    

    或者使用 ERE:

    # Gnu sed need -re instead of -Ee
    sed -Ee '/^[[:space:]]*(#|$)/d' test.in
    

    使用 ERE,grep 也可以轻松完成:

    # Not sure if Gnu grep needs -E or -r
    grep -vE '^\s*(#|$)' test.in
    
    # or a BRE
    grep -v '^\s*\(#\|$\)' test.in
    

    【讨论】:

    • 这是最简单的形式吗?
    • 您可以使用扩展的正则表达式做得更好,请参阅我的编辑。
    【解决方案2】:

    grep:

    grep -v '^\s*$\|^\s*\#' temp
    

    在 OSX / BSD 系统上:

    grep -Ev '^\s*$|^\s*\#' temp
    

    【讨论】:

    • 这似乎没有捕捉到 cmets 具有前导空格的情况,请记住。
    • 如果有些行只有空格(空格、制表符等),它将不起作用。下面为我​​工作。 egrep -v '^[[:space:]]*$|^ *#' &lt;file_name&gt;
    • egrep -v '^[[:blank:]]*#|^[[:blank:]]*$' &lt;file_name&gt; 换行符、垂直制表符、换页和回车不是 grep 中一行的一部分(默认情况下),empty 行中可能出现空白跨度>
    • @ChrisStryczynski,您可能不需要转义 |,但我怀疑这与您的 grep 版本(例如 BSD 与 GNU)有关,而不是您选择的 shell。
    • 抱歉,它确实对我有用。我忘了我有 ripgrep 别名为 grep。
    【解决方案3】:

    这个应该做的:

    sed 's/[[:space:]]*#.*//;/^[[:space:]]*$/d' file
    

    在这个输入上:

    Hello everybody
    
    # This is a comment and the previous line was empty
    
    This is a genuine line followed by a comment # this is the comment
    
    
                  # and here a comment in the middle of nowhere
    

    您将获得以下输出:

    Hello everybody
    This is a genuine line followed by a comment
    

    警告。 这种方法不是 100% 万无一失的:如果你有一个井号 (#) 没有开始评论,即它被转义或在字符串中,那么,你可以想象会发生什么。

    【讨论】:

    • 这就是我要找的。您的解决方案是唯一一项删除 CSF #do not delete 字符串之间还有另一个井号的工作,因此它只会输出 IP 地址。感谢您提供此替代答案
    【解决方案4】:

    GNU 代码

    sed -r '/^(\s*#|$)/d;' file
    

    $cat file
        </Directory>
        ErrorLog ${APACHE_LOG_DIR}/error.log
        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        next line is empty
    
           line with leading space
           # line with leading space and #
        LogLevel warn
            #line with leading tab and #
            line with leading tab
        CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined
        #   SSL Engine Switch:
    $sed -r '/^(\s*#|$)/d;' file
        </Directory>
        ErrorLog ${APACHE_LOG_DIR}/error.log
        next line is empty
           line with leading space
        LogLevel warn
            line with leading tab
        CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined
    

    【讨论】:

      【解决方案5】:

      awk:

      awk '!/^ *#/ && NF' file
      
      • !/^ *#/ - 表示选择没有空格的行,后跟# 符号
      • NF - 表示选择非空白行
      • &amp;&amp; - 是一个 and 运算符,它确保如果以上两个都为真,则打印该行。

      【讨论】:

        【解决方案6】:

        egrep -v '^$|^#' /etc/sysctl.conf

        【讨论】:

        • 请用简单的话解释你的答案,而不是只发布代码
        • 这在 /etc/apache2/sites-enabled/000-default.conf 上不起作用
        【解决方案7】:
        grep -v '^$\|^#\|^\s*\#' filename
        

        不包括空行、以 # 开头的行以及在 # 之前只包含空格的行。

        【讨论】:

        • 这与接受的答案确实相同。 ^# 是多余的,因为 ^\s*# 匹配零个或多个空格,后跟一个哈希。
        【解决方案8】:
        cat filename| egrep -v "^\s*$|^;|^\s*#
        
        • 首先,cat文件
        • egrep -v 删除
        • ^$ 以空行开头
        • ^;; 开头
        • ^\s 匹配任何前导空格,然后匹配任何字符,直到 #

        【讨论】:

        • 这是对cat 命令的一个非常糟糕的用法,你可以在没有cat 的情况下使用egrep
        【解决方案9】:
        grep ^[^#] filename
        
        • ^ - 行首

        • [^#]- 排除#。

        如果你在行首有空格,它将不起作用。

        【讨论】:

          【解决方案10】:
          #!/bin/bash
          
          
          #---------------------------------------------------------------#
          #             Programacion Shell                                #
          #             ------------------                                #
          #  Programa:  xable.sh  (eXecutABLEs)                           #
          ###                                                           ###
          #  OBJETIVO:  Filtrar solo las lineas ejecutables de un shell   #
          #                                    (eXecutABLEs)              #
          ###                                                           ###
          #  Autor...:  Francisco Eugenio Cabrera Perez                   #
          #  Pais....:  Republica Dominicana                              #
          #  Fecha...:  Abril 6 del 2015                                  #
          #---------------------------------------------------------------#
          
                   x_FILE=$1
          if [ -z $x_FILE ];then
             echo
             echo "      $0 :  Sin Argumento^G"; echo
             echo "USO:  $0 ARCHIVO";            echo
          ###
             exit 1
          fi
          #####
          
          
          #  Ignore COMMENTs and lines that...
          #  ---------------------------------
          #      EXPLANATION                            (PATTERN)         OBSERVATION
          #      -----------                            ---------         -----------
          #  1.  Begin_and_End_with_NOTHING             (^$)              NO_Characters
          ###
          #  2.  Begin_with_HASH_symbol                 (^#)              COMMENT
          #  3.  Begin_with_SPACE_and_then_HASH_symbol  (^\s*\#)          COMMENT
          ###
          #  4.  Begin_and_End_with_SPACES              (^[[:space:]]*$)  Only_SPACES
          #  -------------------------------------------------------------------------
          #####
              grep -v '^$\|^#\|^\s*\#' $x_FILE | grep -v "^[[:space:]]*$" | more
          #####
          

          【讨论】:

          • 只显示 eXecutABLEs 行 (xable.sh)
          【解决方案11】:
          grep -v '^$\|^#\|^\s*\#' filename | grep -v "^[[:space:]]*$" | more
          

          【讨论】:

          • 只显示 eXecutABLEs 行
          • 欢迎来到 Stack Overflow!通常,如果答案包含对命令的用途的解释,以及为什么在不介绍其他命令的情况下解决了问题,那么答案会更有帮助。 (该帖子至少被一位用户标记,大概是因为他们认为应该删除没有解释的答案。)
          【解决方案12】:

          使用 Perl:

          perl -lne 'print if ! /^\s*(#.*)?$/' file
          

          这也将忽略 C++ cmets (//)

          perl -lne 'print if ! m{^\s*((#|//).*)?$}' file
          

          【讨论】:

            【解决方案13】:

            小升级

            grep -v '^\s*$\|^#\|^\s*\#' filename

            此代码不包括空行或仅包含空格的行、以 # 开头的行以及 # 之前仅包含空格的行。

            PS:^#^\s*# 不同

            【讨论】:

            • 您愿意解释一下^#^\s*# 有何不同吗?
            • ^# -> 只匹配行首的 hastag 字母
              ^\s*# -> 也匹配前面有空格的 hastag 字母
            • 这是多余的。 /s* 表示“匹配 0 个或多个空格”。因此^\s*# 也将匹配^#
            【解决方案14】:
            sed -n '/^\s*[^#]\|^$/!'p filename
            

            模式将匹配从行首开始的任意数量的空格(或零),然后是任何不是#
            的字符 或空字符串(在 ^ 和 $ 之间什么都没有)。
            为了不匹配它,sed 允许使用 ! 运算符(反转匹配)。现在模式匹配正则表达式不适合的任何内容。
            因此,结合使用 -n(禁止打印任何内容)和 p 标志(打印)行,匹配除模式之外的任何内容。

            【讨论】:

              【解决方案15】:

              使用默认的空格分隔符

              • 空行或空白行只有一个空的$1
              • 第一个非空白字符的行是#,$1 以#开头

              所以,保持简单

              awk '$1 ~ /^[^#]/ ' YourFile
              

              【讨论】:

                【解决方案16】:

                以下内容:

                grep -v '^#\|^$\|^\s+$' file
                

                将隐藏以# 开头的行、空行和仅包含空格的行,使其无法打印到标准输出。请注意,| 字符必须被转义。希望对你有帮助

                【讨论】:

                • 这也不处理前导空格`#`,这在技术上也是一个注释。
                • @ChristopheRoussy 它确实处理前导空格,^\s+$ 部分负责处理
                • 但之后没有前导空格+评论?
                • @ChristopheRoussy 我明白你在说什么,你是对的,正在解决问题,感谢您指出这一点
                【解决方案17】:

                想不出比这更简单的事情了:

                grep -v '^ *#\|^$' filename
                

                您可以使用此文件进行测试:

                # comment
                 # comment with space before
                  # comment with two spaces before
                line with text and # comment at the end
                
                line with text
                

                (编辑为包含一个“*”并处理带有前导空格的 cmets)

                【讨论】:

                • 当注释字符前面有空格时,这将不起作用。
                【解决方案18】:

                这是一个简单的单行 grep。这将摆脱散列和空行。

                grep -ve '^#' -ve '^$' /path/to/the/file
                

                玩得开心。

                【讨论】:

                  猜你喜欢
                  • 2015-10-28
                  • 2015-02-15
                  • 1970-01-01
                  • 2015-10-24
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多