【问题标题】:How to check that a file has more than 1 line in a BASH conditional?如何检查文件在 BASH 条件中是否超过 1 行?
【发布时间】:2014-11-14 19:47:55
【问题描述】:

我需要检查文件是否超过 1 行。我试过这个:

if [ `wc -l file.txt` -ge "2" ]
then
    echo "This has more than 1 line."
fi


if [ `wc -l file.txt` >= 2 ]
then
    echo "This has more than 1 line."
fi

这些只是报告错误。如何检查文件在 BASH 条件中是否超过 1 行?

【问题讨论】:

    标签: bash conditional


    【解决方案1】:
    if [ `wc -l file.txt | awk '{print $1}'` -ge "2" ]
    ...
    

    您应该始终检查每个子命令返回的内容。命令wc -l file.txt 以以下格式返回输出:

    12 file.txt
    

    您需要第一列 - 您可以使用 awkcut 或您选择的任何其他实用程序来提取它。

    【讨论】:

      【解决方案2】:

      命令:

      wc -l file.txt
      

      将生成如下输出:

      42 file.txt
      

      wc 也有助于告诉您文件名。如果您一次检查大量文件并需要个人和总统计信息,它会这样做:

      pax> wc -l *.txt
       973 list_of_people_i_must_kill_if_i_find_out_i_have_cancer.txt
         2 major_acheivements_of_my_life.txt
       975 total
      

      您可以通过在标准输入上提供其数据来阻止wc 执行此操作,因此它不知道文件名:

      if [[ $(wc -l <file.txt) -ge 2 ]]
      

      以下记录显示了这一点:

      pax> wc -l qq.c
      26 qq.c
      
      pax> wc -l <qq.c
      26
      

      顺便说一句,你会注意到我也改用 [[ ]]$()

      我更喜欢前者,因为它由于向后兼容性(主要与字符串拆分有关)而问题较少,而后者因为嵌套可执行文件要容易得多。

      【讨论】:

        【解决方案3】:

        使用mapfile 的纯 bash (≥4) 可能性:

        #!/bin/bash
        
        mapfile -n 2 < file.txt
        if ((${#MAPFILE[@]}>1)); then
            echo "This file has more than 1 line."
        fi
        

        mapfile 内置函数将从stdin 读取的内容存储在一个数组中(默认为MAPFILE),每个字段一行。使用-n 2 使其最多读取两行(为了提高效率)。之后,您只需要检查数组MAPFILE 是否有多个字段。这种方法非常有效。

        作为一个副产品,文件的第一行存储在${MAPFILE[0]},以备不时之需。您会发现尾随的换行符没有被修剪。如果您需要删除尾随换行符,请使用-t 选项:

        mapfile -t -n 2 < file.txt
        

        【讨论】:

          【解决方案4】:

          怎么样:

          if read -r && read -r
          then
            echo "This has more than 1 line."
          fi < file.txt
          

          需要-r 标志来确保行继续字符不会将两行合二为一,这将导致以下文件仅报告一行:

          This is a file with _two_ lines, \
              but will be seen as one.
          

          【讨论】:

          • @paxdiablo 你是对的。谢谢。人们可以争论第一行以反斜杠结尾的两行是否应该被视为一行,因为这应该由应用程序定义。但是由于wc -l 忽略了反斜杠,所以这里也应该忽略它。
          【解决方案5】:

          如果您正在处理大文件,这个awk 命令比使用wc 快得多:

          awk 'BEGIN{x=0}{if(NR&gt;1){x=1;exit}}END{if(x&gt;0){print FILENAME,"has more than one line"}else{print FILENAME,"has one or less lines"}}' file.txt

          【讨论】:

            【解决方案6】:

            改变

            if [ `wc -l file.txt` -ge "2" ]

            if [ `cat file.tex | wc -l` -ge "2" ]

            【讨论】:

            • 它剥夺了我的背包,你需要那些
            • 感谢您的回答!你能解释一下这是做什么的以及它是如何解决最初提问者的问题的吗?
            猜你喜欢
            • 2012-04-15
            • 1970-01-01
            • 2014-10-30
            • 2014-05-11
            • 1970-01-01
            • 2021-12-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多