如果成功则通过管道传输命令的输出

如果成功则通过管道传输命令的输出
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有问题的命令正在寻找最老的目录中的文件。这个相同的函数可以重命名为oldestand 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。

相关内容