有几个微妙的东西可以帮助你的脚本。在读取文件名之前,您应该设置IFS
(内部字段分隔符),使其仅在newline
处中断。这将确保您获得完整的文件名,如果它包含空格并且没有被引用。读取文件名后恢复IFS
。您还需要检查$line
是否已在read
之后被读取,以确保在数据文件最后一行末尾没有newline
的情况下得到最后一行。
此外,每当你从用户读取一个文件名,你应该确认它是一个有效的文件名试图从中读取数据之前:
#!/bin/bash
oifs=$IFS # save internal field separator
IFS=$'\n' # set IFS to newline (if whitespace in path/name)
echo -n "Enter file path/name: " # suppress newline
read fname # read full-path/filename
IFS=$oifs # restore default IFS=$' \t\n'
[ -r "$fname" ] || { # validate input file is readable
printf "error: invalid filename '%s'\n" "$fname"
exit 1
}
while read line || [ -n "$line" ] # protect against no newline for last line
do
name=$line
echo "Text read from file - $name"
done < "$fname" # double-quote fname
exit 0
样品使用/输出:
$ bash readfn.sh
Enter file path/name: dat/ecread.dat
Text read from file - read: 4163419415 0 0 4163419415 0 4395.007 0
Text read from file - read: 4163419415 0 0 4163419415 0 4395.007 0
Text read from file - read: 4163419415 0 0 4163419415 0 4395.007 1
Text read from file - read: 4163419415 0 0 4163419415 0 4395.007 0
非常感谢你的答案,但我只是在一个点混淆。 为什么你在这里使用-r: [-r“$ fname”] || {#验证输入文件可读 printf“错误:无效文件名'%s'\ n”“$ fname” exit 1 } – Umair 2014-11-26 22:44:25
您可以使用'-e'(是否存在),'-f'它是一个文件)等,但最具体的是'-r'(它是可读的[它包含存在,作为一个文件,并且具有足够的权限来阅读])。或者你可以把握机会,而不是测试(不推荐)。重点在于,在验证之前,任何用户输入都应该被视为**可疑**。不知道将会输入什么。 – 2014-11-27 00:17:18
非常感谢。'|| ||这意味着OR,对吗?对不起,这样noob问题,但我刚刚开始.. – Umair 2014-11-27 00:24:30