为什么“ ls -1 $ fl | wc -l”在我的for循环中不返回值0?

时间:2019-03-27 14:28:54

标签: bash shell

我试图在for循环中添加一个条件,以检查文件是否存在以及文件大小> 0 KB。

周期文件包含每月数据:

20180101
20180201
20180301
20180401
20180501

每个月都会创建一个单独的文件。假设一个月未创建文件(20180201),则下面的循环应终止。 例如:

xxx_20180101.txt
xxx_20180301.txt
xxx_20180401.txt
xxx_20180501.txt
if [[ $STATUS -eq 0 ]]; then
     for per in  `cat ${PATH}/${PERIOD}.txt | cut -f 1 -d";"`
     do
        for fl in `ls -1 ${PATH}/${FILE} | grep ${per}`
        do

        if [[ `ls -1 $fl | wc -l` -eq 0 ]]; then
            echo "File not found"
            STATUS=1

            else
        if [[ -s "$fl" ]];  then
                       echo "$fl contain data.">>/dev/null
           else

           echo "$fl File size is 0KB"
           STATUS=1
                    fi
             fi
        done
    done
fi      

但是,如果执行if条件,ls -1 $fl | wc -l不会返回0值。

3 个答案:

答案 0 :(得分:3)

以下是最佳做法重写的示例。

注意:

  • 我们(实际上,必须 不要)不要使用名为PATH的变量来存储用于查找数据文件的目录;这样做会覆盖用于查找要执行的程序的PATH环境变量。
  • ls不在任何地方使用;它是旨在产生供人类消费而不是机器的输出的工具。
  • 通过while read循环来完成输入的读取;有关更多详细信息,请参见BashFAQ #1。注意,循环的输入源是在最后建立的。请参阅done之后的重定向。
  • 在这里使用stat -c查找文件大小;有关更多选项的信息,可移植到不支持stat -c的平台上,请参见BashFAQ #87
  • 由于文件名格式正确(在输入文件的子字符串之前带有下划线,在该子字符串之后带有.txt),因此我们正在对glob进行优化,以仅查找与该限制匹配的名称。这也会阻止搜索001来找到xxx_0015.txtxxx_5001.txt等。
#!/usr/bin/env bash
#              ^^^^ -- NOT /bin/sh; this lets us use bash-only syntax

path=/provided/by/your/code # replacing buggy use of PATH in original code
period=likewise             # replacing use of PERIOD in original code
shopt -s nullglob           # generate a zero-length list for unmatched globs

while IFS=';' read -r per _; do

  # populate an array with a list of files with names containing $per
  files=( "$path/$period/"*"_${per}.txt" )

  # if there aren't any, log a message and proceed
  if (( ${#files[@]} == 0 )); then
    echo "No files with $per found in $path/$period" >&2
    continue
  fi

  # if they *do* exist, loop over them.
  for file in "${files[@]}"; do
    if [[ -s "$file" ]]; then
      echo "$file contains data" >&2
      if (( $(stat -c +%s -- "$file") >= 1024 )); then
        echo "$file contains 1kb of data or more" >&2
      else
        echo "$file is not empty, but is smaller than 1kb" >&2
      fi
    else
      echo "$file is empty" >&2
    fi
  done
done < "$path/$period.txt"

答案 1 :(得分:0)

您在这里完成工程。只需使用句点遍历文件的内容,然后在文件列表中搜索每个句点即可。像这样:

for per in `cat periods.txt`
do
    if ls | grep -q "$per"; then
        echo "$per found";
    else
        echo "$per not found"
    fi
done

答案 2 :(得分:0)

这是米哈伊尔答案的重构,其中消除了标准的http://shellcheck.net/警告。我还不能完全理解实际问题,以猜测这是否真的可以解决OP的问题。

while IFS='' read -r per; do
    if [ -e "xxx_$per.txt" ]; then
        echo "xxx_$per.txt found" >&2
    else
        echo "xxx_$per.txt not found" >&2
    fi
done <periods.txt