Bash - if语句未自动运行

时间:2017-10-20 16:44:21

标签: linux bash ubuntu unix if-statement

我在使用Ubuntu 17.04机器编写的bash脚本时遇到了一个非常奇怪的问题。

我有一个txt文件,其中包含有关此方式的人员信息:

号码姓氏城市州

通过这些信息,我必须创建一个按州运作的组织系统。例如,使用像这样的列表

123阿兰史密斯new_york NEW_YORK

123 bob smith buffalo NEW_YORK

123 charles smith los_angeles CALIFORNIA

123 dean smith mobile ALABAMA

计算结束时的结果应该是三个名为NEW_YORK,CALIFORNIA和ALABAMA的新文件,其中包含居住在那里的人。

该脚本将名称列表作为参数。我在for循环中实现了一个if语句(该条件由对文件存在的测试决定,以防万一有更多的人生活在某个状态),奇怪的是,除非我在程序中按Enter键,否则它不会运行在跑。结果是对的,我得到了合适人物的文件,但是我感到困惑的是我必须按回车才能使代码正常工作,这对我来说没有意义。

这是我的代码:

#!/bin/bash

clear

#finding how many file lines and adding 1 to use the value as a counter later
fileLines=`wc -l addresses | cut -f1 --delimiter=" "`
(( fileLines = fileLines+1 ))

for (( i=1; i<$fileLines; i++ ))
do    
    #if the file named as the last column already exists do not create new one
    test -e `head -n$i | tail -n1 | cut -f5 --delimiter=" "`
    if [ $? = 0 ]
    then
        head -n$i $1 | tail -n1 >> `head -n$i $1 | tail -n1 | cut -f5 --delimiter=" "`
    else
        head -n$i $1 | tail -n1 > `head -n$i $1 | tail -n1 | cut -f5 --delimiter=" "`
    fi
done

echo "cancel created files? y/n"
read key

if [ $key = y ]
then
    rm `ls | grep [A-Z]$`
    echo "done"
    read
else
    echo "done"
    read
fi

clear

我在这里做错了什么?而且,为什么它不告诉我某些事情是错的(显然有)?

1 个答案:

答案 0 :(得分:0)

直接的问题(由@that其他人指出)是在行:

test -e `head -n$i | tail -n1 | cut -f5 --delimiter=" "`

head命令没有给出要读取的文件名,所以它从stdin(即你)读取。但是我会彻底改变整个剧本,因为你是以非常低效的方式进行的。如果你有一个1000行的文件,你运行head来读取第一行(实际上是3次),然后是前两行(三次),然后是前三行...完成这段时间后,head已经读取了文件的第一行3000次,然后tail已经丢弃了2997次。你只需要阅读一次。

当迭代这样的文件时,你只需逐行阅读文件就好了,用这样的东西:

while read line; do
    # process $line here
done <"$1"

但在这种情况下,还有一个更好的工具。 awk非常擅长处理这样的文件,它可以非常简单地处理任务:

awk '{ if($5!="") { print $0 >>$5 }}' "$1"

(注意:我还放入if以确保有第五个字段/忽略空白行。如果没有检查,它将只是awk '{ print $0 >>$5 }' "$1")。

另外,命令:

rm `ls | grep [A-Z]$`

......这是一种非常奇怪而脆弱的方式。解析ls的输出通常是一个坏主意,而且还有一个更简单的方法:

rm *[A-Z]

最后,我建议您通过shellcheck.net运行脚本,因为它会指出其他一些问题(例如,未引用的变量引用)。