在 wc 失败的 shell 脚本中获取文件的行数

Getting the line count of a file in a shell script with wc failing

我的脚本检查参数是文件还是文件夹 如果它是一个文件,他计算行数 之后,如果行数很大,那么 20 或更少,他会执行一些指令 问题出在这条指令n= cat $a | wc -l

我的脚本:

#!/usr/bin/env bash
echo 'Hello this is the test of' `date`
echo 'arguments number is ' $#
if [ $# -eq 4 ]
then
    for a in $@
    do
    if [ -d $a ]
    then
        ls $a > /tmp/contenu
        echo "contenu modified"
    elif [ -f $a ]
        then
#        this instruction must set a numeric value into n
            echo "my bad instruction"
            n=  cat $a | wc -l
            echo "number of lines  = " $n
#        using the numeric value in a test (n must be numeric and takes the number of lines in the current file)
            if [ $n -eq 0  ]
            then
                echo "empty file"
            elif [ $n -gt 20 ]
            then
                echo ` head -n 10 $a `
            else
                cat $a
            fi
    else
        echo "no file or directory found"
    fi
    done
else
echo "args number must be 4"
fi

这是执行错误指令的输出

my bad instruction
5
number of lines  = 
ExamenEx2.sh: line 19: [: -eq : opérateur unaire attendu

n= cat $a | wc -l 行是违规指令。永远记住 bash shell 脚本是极其区分大小写的。 shell 将您的命令解释为必须 运行 两个单独的命令

n=  cat $a | wc -l
#^^ ^^^^^^^^^^^^^^
#1         2

第一部分只是将一个空字符串存储到变量 n 中,接下来打印存储在变量 a 中的文件的行数。请注意 shell 不会为此抛出错误。因为它没有违反语法(只是语义错误)。但是行数从未分配给变量 n.

当您在 LHS 上与空变量进行比较时,遇到条件 if [ $n -eq 0 ] 时会出现错误。

您想 运行 一个命令并存储它的输出,为此您需要命令替换 ($(..))。假设 $a 包含一个文件名就可以

n=$(wc -l < "$a")

请注意,我删除了无用的 cat 用法并将其传送到 wc。但是 wc 可以直接从输入流中读取。

另请注意,您的脚本中有多个不良做法。记得做以下事情

  1. 始终双引号 shell 变量 - "$#""$@"[ -f "$a" ][ -d "$a" ]
  2. 不要使用 `` 进行命令替换,因为它不容易嵌套,而且您可能还会遇到与引用相关的问题。
  3. 如果您确定脚本是否 运行ning 在 bash 下,您可以使用条件表达式 [[,其中可以使用包含空格的变量,而无需在 LHS 上引用