Bash字符串处理(与Java对照) - 5.字符串输入(读取字符串)
Bash字符串处理(与Java对照) - 5.字符串输入(读取字符串)In JavaScanner类:Scanner.hasNext() & Scanner.next() & Scanner.hasNextLine() & Scanner.nextLine()Scanner scanner = new Scanner(System.in);while (scanner.hasNext()) { String msg = scanner.next(); System.out.println(msg);}
?
下面是关于 Scanner.hasNextLine() 和 Scanner.nextLine() 的例子,用于读取输入数据行。
Scanner scanner = new Scanner(System.in);while (scanner.hasNextLine()) { String msg = scanner.nextLine(); System.out.println(msg);}
?
更详细的说明请参考:http://download.oracle.com/javase/1,5.0/docs/api/java/util/Scanner.html
?
Console类:System.console() & Console.readLine() & Console.readPassword()Console类是JDK6加入的,它是对控制台的封装。使用 System.console() 可以获得与当前Java虚拟机关联的控制台,如果有的话。Console.readLine可以读取一行,Console.readPassword可以读取密码。
?
Console console = System.console(); // 获得Console实例对象 if (console != null) { // 判断是否有控制台的使用权 String user = new String(console.readLine("Enter username:")); // 读取整行字符 String pwd = new String(console.readPassword("Enter passowrd:")); // 读取密码,输入时不显示 console.printf("Username is: " + user + "\n"); // 显示用户名 console.printf("Password is: " + pwd + "\n"); // 显示密码 } else { System.out.println("Console is unavailable."); // 提示无控制台使用权限 }?更详细的说明请参考:·http://download.oracle.com/javase/6/docs/api/java/io/Console.html
?
In Bash从标准输入读取使用read命令读取字符串到变量中。但是,如果有反斜杠,将起到转义的作用。\\表示一个\号,\<newline>表示续行,\<char>代表<char>本身。
格式:read VAR
格式:read -p <prompt> VAR
?
[root@node56 ~]# read VAR
hello world
[root@node56 ~]# echo $VAR
hello world
[root@node56 ~]# read -p "Input your number: " VAR
Input your number: 123
[root@node56 ~]# echo $VAR
123
[root@node56 ~]# read VAR
yes\tno
[root@node56 ~]# echo $VAR
yestno
[root@node56 ~]#
?
?
读取一行文本,但是取消反斜杠的转义作用。
格式:read -r VAR
格式:read -p <prompt> -r VAR
54321
?
读取指定数量字符格式:read -n <nchars> VAR
格式:read -p <prompt> -n <nchars> VAR
?
在指定时间内读取格式:read -t <seconds> VAR
格式:read -p <prompt> -t <seconds> VAR
?
?
从文件中读取格式:read VAR <file.txt
对于read命令,可以指定-r参数,避免\转义。
格式:read -r VAR <file.txt
错误:cat file.txt | read VAR??? (此处read命令将会在子进程中执行,子进程无法更改父进程的变量)
?
[root@web ~]# cat input.txt
Some text here
with backslash \ here
dollar $HOME meet
[root@web ~]# cat input.txt | read VAR
[root@web ~]# echo $VAR
[root@web ~]# read VAR <input.txt
[root@web ~]# echo $VAR
Some text here
[root@web ~]# read VAR1 VAR2 VAR3 VAR4<input.txt
[root@web ~]# echo "VAR1=$VAR1 VAR2=$VAR2 VAR3=$VAR3 VAR4=$VAR4"
VAR1=Some VAR2=text VAR3=here VAR4=
[root@web ~]# read VAR1 VAR2<input.txt
[root@web ~]# echo "VAR1=$VAR1 VAR2=$VAR2"
VAR1=Some VAR2=text here
[root@web ~]#
上面的直接对read命令输入重定向,只能读取输入文件中的一行。
?
如果需要读取整个文件,最好将其写在一个代码块中。
?
{ read LINE1; read LINE2; read LINE3; } <input.txt
注意每个read命令之后都要以分号结束。
?
[root@web ~]# { read LINE1; read LINE2; read LINE3; } <input.txt
[root@web ~]# echo $LINE1
Some text here
[root@web ~]# echo $LINE2
with backslash here
[root@web ~]# echo $LINE3
dollar $HOME meet
[root@web ~]#
上面LINE2中\ 没有读取出来,因为在没有加上-r参数时,read会转义。
?
现在加上-r参数来测试一下。
{ read -r LINE1; read -r LINE2; read -r LINE3; } <input.txt
?
[root@web ~]# { read -r LINE1; read -r LINE2; read -r LINE3; } <input.txt
[root@web ~]# echo $LINE1
Some text here
[root@web ~]# echo $LINE2
with backslash \ here
[root@web ~]# echo $LINE3
dollar $HOME meet
[root@web ~]#
?
从Here Document读取错误:read VAR <<EOF
some string
EOF
正确:{ read VAR; } <<EOF
some string
EOF
问题:为什么写在代码块中才能读取呢?
?
[root@web ~]# read VAR <<EOF
> some string
> EOF
[root@web ~]# echo "$VAR"
[root@web ~]# { read VAR; } <<EOF
> hello
> EOF
[root@web ~]# echo "$VAR"???????
hello
[root@web ~]#
?
从Here String读取read VAR <<< "some string"
read VAR <<< "$STR"
?
[root@web ~]# read VAR <<< "some string"
[root@web ~]# echo $VAR
some string
[root@web ~]#
?
?
补充:关于 cat input.txt | read VAR 的问题
先说一下我对管道线的理解:管道线两侧的命令,前一个命令的输出(标准输出),将作为后一个命令的输入(标准输入)。两侧的命令都是在子进程中执行的,都有各自独立的地址空间,子进程会继承(复制)父进程所有的环境变量。子Shell(subshell)是一种特殊的子进程,它会继承(复制)父Shell的所有变量;对于非子Shell进程(外部命令),只有环境变量会被继承(复制)。但是,子进程一旦启动,它所有的变量只在它的进程空间中有效,它对变量的修改都是对自己范围之内的变量的修改,对父进程相同名称的变量是没有影响的。而子进程启动之后,它的父进程对父进程变量的修改,对子进程相同名称的变量也是没有影响的。
echo "variable = $variable" # variable = initial_value[root@web ~]# cat input.txt
Some text here
with backslash \ here
dollar $HOME meet
[root@web ~]# cat input.txt | read VAR
[root@web ~]# echo $VAR
?
上面的cat input.txt的输出将作为read VAR的输入。
[root@web ~]# cat input.txt | { read VAR; echo $VAR; }
Some text here
可以看到管道线后面的子Shell中确实读到了值。
[root@web ~]# echo $VAR
?
但父Shell中的相同变量不会改变。
[root@web ~]#
?
?
本文链接:http://codingstandards.iteye.com/blog/1170586? (转载请注明出处)
返回目录:Java程序员的Bash实用指南系列之字符串处理(目录)?
上节内容:Bash字符串处理(与Java对照) - 4.字符串输出
下节内容:Bash字符串处理(与Java对照) - 6.判断字符串是否为空(不为空)
?
?
1 楼 山风小子 2011-09-13 不错,很详细! 2 楼 superlittlefish 2011-09-13 (此处read命令将会在子进程中执行,子进程无法更改父进程的变量) 不明白为什么会子进程无法更改父进程的变量 ? 3 楼 codingstandards 2011-09-14 superlittlefish 写道(此处read命令将会在子进程中执行,子进程无法更改父进程的变量) 不明白为什么会子进程无法更改父进程的变量 ?