Bash - if语句不自动运行
我在Ubuntu 17.04机器上编写的bash脚本有一个非常奇怪的问题。Bash - if语句不自动运行
我有一个包含约人以这种方式信息的txt文件:
数名姓城市国家
有了这些相关信息我要创建一个组织系统,通过国家的作品。例如,像这样
123阿兰·史密斯new_york NEW_YORK
123鲍勃·史密斯水牛NEW_YORK
123查尔斯列表史密斯los_angeles CALIFORNIA
123迪恩·史密斯阿拉巴马州墨比尔
结果在计算结束时应该有三个名为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
什么我错在这里做什么?而且,为什么它没有告诉我有什么不对(显然存在)?
眼前的问题(由@that其他人指出)是在该行:
test -e `head -n$i | tail -n1 | cut -f5 --delimiter=" "`
的head
命令没有给出一个文件名从阅读,因此它从标准输入读取(即你)。但是我会剧烈地改变整个脚本,因为你以非常低效的方式来做它。如果你有一个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运行脚本,因为它会指出一些其他问题(如未加引号的变量引用)。
您的'test -e'行不会从文件读取。它从您那里读取。也许你想要“头 - 我$”$ 1“'而不是? (尽管测试是不必要的:第一次不需要使用'>',当不存在时也会创建文件) –
这是行得通的吗?你怎么称呼它?它看起来像是读取标准输入,但是......你只是想按照状态解析文件的行吗? –