如何在 BASH 条件中检查文件是否超过 1 行?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25947072/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 21:40:55  来源:igfitidea点击:

How to check that a file has more than 1 line in a BASH conditional?

bashconditional

提问by Village

I need to check if a file has more than 1 line. I tried this:

我需要检查一个文件是否超过 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

These just report errors. How can I check if a file has more than 1 line in a BASH conditional?

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

回答by paxdiablo

The command:

命令:

wc -l file.txt

will generate output like:

将生成如下输出:

42 file.txt

with wchelpfully telling you the file name as well. It does this in case you're checking out a lot of files at once and want individual as well as total stats:

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

You can stop wcfrom doing this by providing its data on standard input, so it doesn't knowthe file name:

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

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

The following transcript shows this in action:

以下成绩单显示了这一点:

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

pax> wc -l <qq.c
26


As an aside, you'll notice I've also switched to using [[ ]]and $().

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

I prefer the former because it has less issues due to backward compatibility (mostly to do with with string splitting) and the latter because it's far easier to nest executables.

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

回答by gniourf_gniourf

A pure bash (≥4) possibility using mapfile:

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

#!/bin/bash

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

The mapfilebuiltin stores what it reads from stdinin an array (MAPFILEby default), one line per field. Using -n 2makes it read at most two lines (for efficiency). After that, you only need to check whether the array MAPFILEhas more that one field. This method is very efficient.

所述mapfile内置存储它从读出stdin的阵列(在MAPFILE默认情况下),每场一行。使用-n 2使它最多读取两行(为了效率)。之后,您只需要检查数组是否MAPFILE有不止一个字段。这种方法非常有效。

As a byproduct, the first line of the file is stored in ${MAPFILE[0]}, in case you need it. You'll find out that the trailing newline character is not trimmed. If you need to remove the trailing newline character, use the -toption:

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

mapfile -t -n 2 < file.txt

回答by Scrutinizer

How about:

怎么样:

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

The -rflag is needed to ensure line continuation characters don't fold two lines into one, which would cause the following file to report one line only:

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

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

回答by plesiv

if [ `wc -l file.txt | awk '{print }'` -ge "2" ]
...

You should always check what each subcommand returns. Command wc -l file.txtreturns output in the following format:

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

12 file.txt

You need first column - you can extract it with awkor cutor any other utility of your choice.

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

回答by tungufoss

If you're dealing with large files, this awkcommand is much faster than using wc:

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

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

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