如果使用-z或-n的语句,则使用Shell

时间:2017-01-29 23:37:15

标签: bash shell

晚安。

我尝试使用以下代码读取目录中每个生命的每一行,逐行,每行由";"分隔,以显示每行在最后一个分隔字段中的某些内容,但我的if语句不起作用。

以下是一些行的例子。

Name_familyName;1234567890;service_name;date_time_contract;date_time_purchase
Name_familyName;1234567890;service_name;date_time_contract;

正如你可以看到我在最后一个字段中有date_time_purchase值,但有些时候我没有,我试图使用以下代码来检查该行是否在最后一个字段中有数据并显示给我。

#!/bin/bash

files_dir="/directory/sub_directory/*"


for file in $files_dir
do

    total_lines=$(wc -l <$file)
    i=0

    while IFS= read -r line; do


        i=$(($i+1))

        last_field=$(echo "$line" | rev | cut -d";" -f1 | rev)

        if [[ "$total_lines" -gt "$i" ]] && [[ ! -z "$last_field" ]]; then
            info=$(echo $line)
            echo $info

        fi
    done < "$file"

done 

我也尝试使用[[-n $ last_field]],但是它显示了没有最后一个字段的行,我也尝试使用它们有和没有&#34;!&#34;标记

我也调查了这个,但它也没有用: Shell if statements not working as intended

1 个答案:

答案 0 :(得分:2)

试试这个:

#!/bin/bash
files_dir="/directory/sub_directory"
for file in "$files_dir"/*
do
  [[ -f "$file" ]] || continue
  while IFS=";" read -r f1 f2 f3 f4 f5
  do
    [[ "$f5" ]] || echo "$f1;$f2;$f3;$f4;$f5"
  done < "$file"
done

我改变了什么:

  • 我将glob放在for语句中:在那里进行全局操作可以防止引用问题

  • 我添加了一个测试,以确保file变量包含一个文件,因为失败的glob可以使其成为

  • 我摆脱了total_linesi变量,据我所知,实际上什么都没做(他们使用的条件似乎是多余的)

    < / LI>
  • 我在while循环中使用直接read语句替换了管道,该语句使用分号(IFS=";")分隔行并分配了五个字段。

  • 使用[[ "$var" ]][[ ! -z "$var" ]]的功能相同,但更简单易读。

  • 使用内部带有$()的命令替换echo来分配变量,然后在第二个语句中回显此值,这是多余的。只有一个echo语句,没有替换就足够了。

请注意,在两个实例中,我使用||“OR”逻辑运算符。结果是,只有在测试失败时才执行测试后的语句。它比完整if/then/fi更简洁。 continue关键字允许提前终止当前迭代并跳转到下一次迭代。它不同于break,它将退出循环,跳过所有剩余的迭代,而不仅仅是当前的迭代。