INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml | head -1 | xargs basename`
我想head -1
仅当第一个命令成功时才执行第二个命令()。如何改进这个命令?
答案1
尝试这个:
INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml | head -1 | xargs -r basename`
传递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`
另请注意,我在 周围添加了引号$MY_DIR
。这样,如果$MY_DIR
包含空格,该命令就不会失败。
如果您使用的是现代 shell(例如 bash),则应该使用$( )
捕获 shell 而不是反引号。您还应该考虑更改变量的样式。通常应避免在脚本中使用全大写的变量名称。该样式通常保留用于保留变量和环境变量。
input_file=$(ls -rt "$my_dir"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename)
答案2
在管道中,所有命令都是同时启动和运行的,而不是一个接一个地运行。所以你需要将输出存储在某个地方。
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
请注意,它假设文件名不包含换行符。使用xargs
还意味着空白字符、单引号和双引号以及反斜杠的问题。不加引号的变量将意味着空格、制表符和通配符的问题。忘记--
意味着以-
.
要获取最旧文件的基本名称,zsh
而不对字符进行任何限制(也避免了命令参数大小有限的问题):
first_file_name=($MY_DIR/FILE.*.xml(Om[1]:t))
如果没有匹配,该命令将失败并中止脚本。您还可以这样做:
first_file_name=($MY_DIR/FILE.*.xml(NOm[1]:t))
在这种情况下,first_file_name
如果匹配则数组将包含 1 个元素,如果不匹配则包含 0。然后你可以这样做:
if (($#first_file_name)); then
printf 'Match: %s\n' $first_file_name
else
echo >&2 No match
fi
答案3
在目录中查找最新修改的文件:
latest() {
local file path=${1:-.} ext=${2-} latest
for file in "${path%/}"/*"$ext"; do
[[ $file -nt $latest ]] && latest=$file
done
[[ $latest ]] && printf '%s\n' "$latest"
}
用法:latest [directory/path/ [.extension]]
basename
使用参数扩展而不是调用。
in_file=$(latest in/my/dir .xml)
base_fn=${in_file##*/} base_fn=${base_fn%.*}
在包含以下内容的目录中:
foo.xml bar.xml baz.xml newest.xml
base_fn 变量的内容为:newest
为了正确使用它来满足您的请求的目的:
check_dir=/path/to/check
check_ext=.xml
if in_file=$(latest "$check_dir" "$check_ext"); then
base_fn=${in_file##*/} base_fn=${base_fn%.*}
else
printf '%s\n' "No file found in $check_dir" >&2
fi
编辑:在审查问题后,我意识到ls
有问题的命令正在寻找最老的目录中的文件。这个相同的函数可以重命名为oldest
and has[[ $file -ot $oldest ]] && oldest=$file
来实现相同的效果。对于任何混乱,我们深表歉意。
需要注意的重要一点是,在人类的任何情况下,您绝对不应该解析 ls 的输出。绝不。
答案4
我认为这里最好的选择是:
ls -rf $MY_DIR/FILE.*.xml
if [ $? -eq 0 ]; then
INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml|head -1|xargs basename `
else
echo "Error!"
fi
如果没有文件,则 ls 的返回码为 2,但如果找到某个文件,则返回码为 0。