gil*_*och 68 bash command-line stdin
如何编写一个脚本来接受来自文件名参数或标准输入的输入?
例如,您可以使用less
这种方式。一个可以执行less filename
和等效cat filename | less
。
有没有一种简单的“开箱即用”的方式来做到这一点?还是我需要重新发明轮子并在脚本中编写一些逻辑?
sus*_*tus 68
如果 file 参数是脚本的第一个参数,请测试是否有参数 ( $1
) 并且它是一个文件。否则从标准输入读取输入 -
所以你的脚本可能包含这样的内容:
#!/bin/bash
[ $# -ge 1 -a -f "$1" ] && input="$1" || input="-"
cat $input
Run Code Online (Sandbox Code Playgroud)
例如,那么你可以像这样调用脚本
./myscript.sh filename
Run Code Online (Sandbox Code Playgroud)
或者
who | ./myscript.sh
Run Code Online (Sandbox Code Playgroud)
编辑 脚本的一些解释:
[ $# -ge 1 -a -f "$1" ]
- 如果至少有一个命令行参数 ( $# -ge 1
) AND (-a operator) 第一个参数是一个文件(-f 测试“$1”是否是一个文件),那么测试结果为真。
&&
是 shell 逻辑 AND 运算符。如果测试为真,则分配input="$1"
并cat $input
输出文件。
||
是外壳逻辑 OR 运算符。如果测试为假,则||
解析以下命令。输入分配给“-”。该命令cat -
从键盘读取。
总而言之,如果提供了 script 参数并且它是一个文件,那么变量 input 将分配给文件名。如果没有有效参数,则 cat 从键盘读取。
小智 13
read
从标准输入读取。从文件 ( ./script <someinput
) 或通过管道 ( dosomething | ./script
)重定向它不会使其工作方式不同。
您所要做的就是遍历输入中的所有行(这与遍历文件中的行没有区别)。
(示例代码,只处理一行)
#!/bin/bash
read var
echo $var
Run Code Online (Sandbox Code Playgroud)
将回显标准输入的第一行(通过<
或|
)。
小智 5
你没有提到你打算使用什么 shell,所以我会假设 bash,尽管这些都是 shell 中非常标准的东西。
可以通过变量访问参数$1
- $n
($0
返回用于运行程序的命令)。假设我有一个脚本,它只cat
输出 n 个文件,它们之间有一个分隔符:
#!/usr/bin/env bash
#
# Parameters:
# 1: string delimiter between arguments 2-n
# 2-n: file(s) to cat out
for arg in ${@:2} # $@ is the array of arguments, ${@:2} slices it starting at 2.
do
cat $arg
echo $1
done
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我们将文件名传递给 cat。但是,如果您想转换文件中的数据(无需明确写入和重写),您还可以将文件内容存储在变量中:
file_contents=$(cat $filename)
[...do some stuff...]
echo $file_contents >> $new_filename
Run Code Online (Sandbox Code Playgroud)
就从 stdin 读取而言,大多数 shell 都有一个非常标准的read
内置函数,尽管在指定提示的方式上存在差异(至少)。
该猛砸内建手册页有一个非常简明的解释read
,但我更喜欢猛砸黑客网页。
简单地:
read var_name
Run Code Online (Sandbox Code Playgroud)
要设置多个变量,只需提供多个参数名称即可read
:
read var1 var2 var3
Run Code Online (Sandbox Code Playgroud)
read
然后将 stdin 中的一个单词放入每个变量中,将所有剩余的单词转储到最后一个变量中。
? read var1 var2 var3
thing1 thing2 thing3 thing4 thing5
? echo $var1; echo $var2; echo $var3
thing1
thing2
thing3 thing4 thing5
Run Code Online (Sandbox Code Playgroud)
如果输入的单词少于变量,则剩余的变量将为空(即使之前已设置):
? read var1 var2 var3
thing1 thing2
? echo $var1; echo $var2; echo $var3
thing1
thing2
# Empty line
Run Code Online (Sandbox Code Playgroud)
我-p
经常使用标志来提示:
read -p "Enter filename: " filename
Run Code Online (Sandbox Code Playgroud)
注意:ZSH 和 KSH(可能还有其他)使用不同的提示语法:
read "filename?Enter filename: " # Everything following the '?' is the prompt
Run Code Online (Sandbox Code Playgroud)
这并不是真正的read
技巧,但我经常将它与read
. 例如:
read -p "Y/[N]: " reply
reply=${reply:-N}
Run Code Online (Sandbox Code Playgroud)
基本上,如果变量(reply)存在,则返回自身,但如果是空的,则返回以下参数(“N”)。
归档时间: |
|
查看次数: |
124896 次 |
最近记录: |