Gov*_*las 18 shell pipe output
INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml | head -1 | xargs basename`
Run Code Online (Sandbox Code Playgroud)
我只想head -1在第一个命令成功时执行第二个命令 ( )。如何改进此命令?
小智 13
尝试这个:
INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml | head -1 | xargs -r basename`
Run Code Online (Sandbox Code Playgroud)
传递xargs该-r标志将使其仅basename在从标准输入 ( head -1) 中读取至少一项时才运行。
head -1 将运行,但您不会看到或捕获它的任何输出。
此外,如果您不希望用户看到来自 的任何错误输出ls,您可以将ls的 stderr 流重定向到/dev/null。
INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename`
Run Code Online (Sandbox Code Playgroud)
另请注意,我在$MY_DIR. 这样,如果$MY_DIR包含空格,该命令将不会失败。
如果您使用的是现代 shell,例如 bash,则应该使用$( )捕获 shell 而不是反引号。您还应该考虑更改变量的样式。您通常应该避免在脚本中使用全大写的变量名。该样式通常保留用于保留变量和环境变量。
input_file=$(ls -rt "$my_dir"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename)
Run Code Online (Sandbox Code Playgroud)
在管道中,所有命令都是同时启动和运行的,而不是一个接一个。所以你需要将输出存储在某个地方。
if ls_output=$(ls -rtd -- "$MY_DIR"/FILE.*.xml); then
first_file=$(printf '%s\n' "$ls_output" | head -n 1)
first_file_name=$(basename -- "$first_file")
fi
Run Code Online (Sandbox Code Playgroud)
请注意,它假定文件名不包含换行符。使用xargs也意味着空白字符、单引号和双引号以及反斜杠的问题。不加引号的变量意味着空格、制表符和通配符出现问题。忘记--意味着文件名以-.
要在zsh没有任何字符限制的情况下获取最旧文件的基本名称(也避免了命令参数大小受限的问题):
first_file_name=($MY_DIR/FILE.*.xml(Om[1]:t))
Run Code Online (Sandbox Code Playgroud)
如果没有匹配项,该命令将失败并中止脚本。你也可以这样做:
first_file_name=($MY_DIR/FILE.*.xml(NOm[1]:t))
Run Code Online (Sandbox Code Playgroud)
在这种情况下,first_file_name如果匹配,则数组将包含 1 个元素,否则为 0。然后你可以这样做:
if (($#first_file_name)); then
printf 'Match: %s\n' $first_file_name
else
echo >&2 No match
fi
Run Code Online (Sandbox Code Playgroud)