是否可以按文件名按字母顺序排序输出find … -exec ls -ls ;
?
这是我的 cron 命令:
find /home/setefgge/public_html -type f -ctime -1 -exec ls -ls {} \;
这个命令在大多数情况下都可以正常工作。但结果没有按任何有意义的顺序排序。如果它们按文件名字段排序,将会非常有帮助。
答案1
我假设您的文件名不包含换行符。
find /home/setefgge/public_html -type f -ctime -1 -exec ls -nls {} + | sort -k 10
使用+
而不是;
终止-exec
操作可以通过批处理 的调用来加快速度ls
。您可以通过命令通过管道进行排序sort
;告诉它从第 10 个字段开始排序(前 9 个字段是元数据:块、权限、链接计数、用户、组、大小和 3 个日期/时间字段)。该选项-n
指示ls
对用户和组使用数值,这可以避免用户或组名称包含空格的风险。
或者,使用 zsh,您可以通过使用来摆脱对任何名称的假设全局限定符收集和排序文件zargs
ls
如果命令行太长,则运行多次。您确实需要 GNU ls
(特别是它的-f
选项)来避免重新排序ls
(另一种方法是ls
使用 zsh进行模拟zstat
)。
autoload -U zargs
zargs -- /home/setefgge/public_html/**/*(.c-2) -- ls -lnsf
答案2
为什么不通过排序传递 find 的结果,然后对每一行执行 ls ?
find . -type f -ctime -1 | sort | while IFS= read -r filename; do ls -ls "$filename"; done
答案3
POSIX 对于 ong 列表中的日期有这样的说法ls
-l
:
该
<date and time>
字段应包含文件上次修改时的适当日期和时间戳。在 POSIX 语言环境中,该字段应等效于以下日期命令的输出:
date "+%b %e %H:%M"
...如果文件在过去六个月内被修改,或者:
date "+%b %e %Y"
考虑到这一点,并确保如果文件名中有任何换行符,它们也会使用 POSIX 指定的选项正确匹配,那么为结果ls -q
准备正则表达式相对容易,根本不需要:ls
find
d=$(date "+%b %e") y=$(date --date=yesterday "+%b %e")
echo "$d" "$y"
###OUTPUT###
Jul 5 Jul 4
grep
为此,您将仅返回包含表示今天或昨天日期的字符串的行。下面的命令对此做了一些补充:
ls -alRcq | sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"
ls
选项包括:
-a
返回目录中的所有文件 - 包括以 a 开头的文件.dot
-l
长列表-R
递归列出所有子目录-c
显示修改时间而不是访问时间-q
返回 shell glob ,而不是文件名中的?
不可打印字符或ab 字符\t
这些结果将传递到仅匹配的|pipe
文件sed
:
- 路径名前面的空行和后面的行
- 以以下开头的行
-
(换句话说 - 不适d
用于目录)其中还包含您的date
. - 但它不会打印路径名行,除非它们命名的目录实际上包含您已过滤的文件。
输出如下所示:
ls -alRcq --color=always |
sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"
###OUTPUT###
.:
-rw------- 1 mikeserv mikeserv 2086 Jul 4 10:52 .bash_history
-rw------- 1 mikeserv mikeserv 2657 Jul 4 15:20 .lesshst
-rw-r--r-- 1 mikeserv mikeserv 681 Jul 5 05:18 .zdirs
-rw------- 1 mikeserv mikeserv 750583 Jul 5 08:28 .zsh_history
-rw-r--r-- 1 mikeserv mikeserv 166 Jul 4 23:02 Terminology.log
-rw-r--r-- 1 mikeserv mikeserv 433568 Jul 4 13:34 shot-2014-06-22_17-10-16.jpg
-rw-r--r-- 1 mikeserv mikeserv 445192 Jul 4 13:34 shot-2014-06-22_17-11-06.jpg
./.cache/efreet:
-rw------- 1 mikeserv mikeserv 37325 Jul 4 22:51 desktop_localhost_C.eet
-rw------- 1 mikeserv mikeserv 37325 Jul 4 23:30 desktop_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv 24090 Jul 4 22:51 desktop_util_localhost_C.eet
-rw------- 1 mikeserv mikeserv 24090 Jul 4 23:30 desktop_util_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv 16037 Jul 4 23:30 icon_themes_localhost.eet
-rw------- 1 mikeserv mikeserv 3117 Jul 4 23:30 icons___efreet_fallback_localhost.eet
-rw------- 1 mikeserv mikeserv 768039 Jul 4 23:30 icons_gnome_localhost.eet
-rw------- 1 mikeserv mikeserv 18589 Jul 4 23:30 icons_hicolor_localhost.eet
./.config:
-rw-r--r-- 1 mikeserv mikeserv 30 Jul 4 19:10 pavucontrol.ini
./.config/chrome:
-rw-r--r-- 1 mikeserv mikeserv 94332179 Jul 4 13:36 conf.tar.lz4.bak
是的,它甚至可以与LS_COLORS
- 当然,这对您来说可能是一个低优先级cron
,但是,嘿,您的选择是开放的。
无论如何,与其他一些可能的解决方案相比,这提供了一些显着的优势。
首先,
find
+ls
涉及多个调用 - 这只涉及一个ls
进程,这就是为什么它能够可靠地对所有内容进行排序 - 默认情况下这样做 - 因此sort
也成为辅助的。任何涉及
find
andsort
的解决方案ls
都在做全部工作的两次。ls
并将find
解析每个路径名和stat
每个文件。ls
并且sort
都会对所有结果进行排序。最好只使用单个ls
.当然还有这个答案的
date
和部分。sed
需要注意的重要一点是,您完成了最困难的部分并首先获取正则表达式 - 并且仅一次 - 然后您只修剪单个结果列表,而不是说,获取结果,获取结果,对结果进行排序和对结果进行排序。这不会像其他解决方案那样破坏包含换行符的文件名。这个解决方案确实有其自身的警告 - 我接下来会解释 - 但它们很微小且易于处理。在我看来,这是最强大的解决方案。
在两种情况下,上述命令可能会给您带来问题。第一个涉及?
文件名中的 glob - 虽然它已经是比此处提供的任何其他解决方案更强大的解决方案,并且您遇到 a 的可能性?
本身足够小,但有可能解决这些 glob可以匹配多个文件名。请参见这有关此主题的更多信息。
另一种可能性涉及误报 - 例如,如果您有一个文件名实际上date
与我们正在搜索的字符串匹配grep
,但实际上在任何一天都没有修改过。我不认为这是一个问题,但是,如果是这样,请询问一下,我可能可以帮助您使正则表达式更具体,以便处理这个问题。
答案4
实际上,您可以组合使用 find、xargs 和 ls。
这是一个示例命令:find . -type f -print0 | xargs -0 ls -lt
find
会递归查找当前目录下的所有文件。ls
xargs 将在一次调用中将此文件列表传递给命令(前提是find
返回的文件数少于ARG_MAX
文件数)。ls -lt
将按时间对这些文件进行排序并格式化输出
为了检索您的系统,ARG_MAX
您可以输入:
$ getconf ARG_MAX
> 2621440