如何通过命令以相反的时间顺序列出文件并将它们作为参数传递给另一个命令?

Tim*_*Tim 7 bash date files arguments

我有一个程序,它在一个命令行中接收一些文件作为参数。我想用倒序列出的目录中的所有文件来调用它。

例如:

我在一个目录中有以下文件以相反的时间顺序

$ ls -tr
 Introduction.pdf  'Object-Oriented Data Model.pdf' 
Run Code Online (Sandbox Code Playgroud)

我可以直接运行我的程序,

myprogram Introduction.pdf  'Object-Oriented Data Model.pdf' 
Run Code Online (Sandbox Code Playgroud)

但我想通过另一个命令来列出文件。由于一个文件名中的空格,这将不起作用:

myprogram $(ls -tr)
Run Code Online (Sandbox Code Playgroud)

我记得解析ls输出不是一个好习惯。我不确定是否find可以提供帮助。

那我能做什么?

谢谢。

roa*_*ima 5

如果您拥有最新版本的 GNU 实用程序,您可以让它们处理以 NULL 结尾的数据。这允许构建不受数据本身中的空格或换行符影响的管道。

我的测试工具是一个名为的快速脚本/tmp/args

#!/bin/bash
echo "This is args with $# value(s)"
for f in "$@"; do echo "> $f <"; done
Run Code Online (Sandbox Code Playgroud)

这是您如何在命令行上提供一系列文件名,按文件上次修改时间排序:

find -type f -printf "%T@ %p\0" | sort -zn | sed -z 's/^[0-9.]* //' | xargs -0 /tmp/args
Run Code Online (Sandbox Code Playgroud)

find命令为每个文件/路径名加上上次修改日期/时间的小数秒表示形式的前缀。这是sort按从最低(最旧)到最高(最新)的顺序处理的。该sed关领先的数条我们刚刚使用排序,并将得到的文件名的设置被传递给xargs。更换%p%P,如果你喜欢省略领先./的文件名。

示例数据

#!/bin/bash
echo "This is args with $# value(s)"
for f in "$@"; do echo "> $f <"; done
Run Code Online (Sandbox Code Playgroud)

示例结果

find -type f -printf "%T@ %p\0" | sort -zn | sed -z 's/^[0-9.]* //' | xargs -0 /tmp/args
Run Code Online (Sandbox Code Playgroud)


小智 3

(IFS=$'\n'; set -f; your_program $(ls -tr))
Run Code Online (Sandbox Code Playgroud)

假设文件名不包含换行符。

例子:

% touch 'a   b'
% touch 'c d'
% touch '*'
% (IFS=$'\n'; set -f; printf '%s\n' $(ls -tr))
e    f
a   b
c d
*
Run Code Online (Sandbox Code Playgroud)

不支持$'...'字符串的标准 shell 的变体:

(IFS='
' ; set -f; your_program $(ls -tr))
Run Code Online (Sandbox Code Playgroud)

简单的 python 包装器,即使文件名包含换行符也可以工作。用法即可this_wrapper your_program *

#! /usr/bin/python
import os
import sys

sys.argv[2:] = sorted(sys.argv[2:], key=os.path.getmtime)
os.execvp(sys.argv[1], sys.argv[1:])
Run Code Online (Sandbox Code Playgroud)