我通常在ksh中使用for构造来快速迭代文件列表以对其执行某些操作。它在这种情况下似乎不起作用:
The file info looks like:
$ ls -l tmp.*
rw------- 1 op general 375 Jul 25 04:09 tmp.zzyhsg4
...
so on. Basically a lot of tmp.* files.
Now when I try
$ ls -lS | grep 'Jul 25' | grep 'tmp.*' | cut -d' ' -f9 | more
tmp.zzyhsg4
..
它将按预期打印文件名。 但是当我尝试下面的
时$ for i in `ls -lS | grep 'Jul 25' | grep 'tmp.*' | cut -d' ' -f9`
>do
>echo $i
>done
这不会打印以tmp。*开头的所有文件的名称,这些文件是在7月25日按大小排序的。它打印尺寸列。有趣的是,如果我用f6替换f10进行切割,它将正确打印月份列。它在f9之后开始破裂。
有什么想法吗?
答案 0 :(得分:1)
要获取名为tmp.*
的所有文件,请使用
$ ls -lS tmp.*
通过剪切,您可以将空间作为分隔符。这将无法正常工作。字段之间的空格数是灵活的,因此您将拥有不同数量的字段。 (每2个空格之间就有一个空字段)
更好地使用find
,它可以将您的文件列表整形为您喜欢的任何形式:
$ find tmp.* -printf "%s %CD %f\\n" | grep "07/25/10" | sort -n
(man find
也可以在find
命令中获取日期过滤)
答案 1 :(得分:1)
我无法准确再现您所描述的内容,但我有一些建议可以编写更可靠的命令。
cut -d' '
按空格分隔字段。如果连续有两个空格,则它们之间有一个空字段。因此,如果您尝试使用Aug 1
而不是Jul 25
,则文件名列会移动1.如果您尝试使用超过6个月的文件,则会替换(5个字符)时间按一个空格,然后是4位数年份。此外,根据您的ls
版本,某些列之间可能有多个空格。另一个问题是某些版本的ls
不会显示group
列。然后一些文件名包含空格。某些文件名包含ls
可能显示为?
的特殊字符。总之,您无法通过计算空格来解析ls -l
的输出,甚至无法通过计算以空格分隔的字段来解析ls -l
的输出。只是不解析ls的输出。
用于生成现有文件名称列表的标准命令是find
。既然你提到Linux,我会提到与GNU find(你在Linux上获得的版本)有关的选项,但不会提到其他unix。
让我们开始简单:列出当前目录中名为tmp.*
的文件。
find . -name 'tmp.*'
我们只想要在7月25日创建的文件,即7天前创建的文件。
find . -name 'tmp.*' -daystart -mtime 7
这很脆弱,因为它明天不起作用。指定精确日期的通常方法是创建最早和最晚允许时间的文件,并告诉find
仅返回这两者之间的日期文件。
touch -t 201007250000 .earliest
touch -t 201007260000 .latest
find . -name 'tmp.*' -newer .earliest \! -newer .latest
rm .earliest .latest
find
命令以递归方式探索子目录。如果你不想要这个:
find . -name 'tmp.*' -daystart -mindepth 1 -maxdepth 1 -mtime 7
如果您希望按大小排序文件:
find . -name 'tmp.*' -daystart -mtime 7 -printf '%s\t%p\n' | sort -n -k 1 | cut -f 2-
最后,如果您要对文件进行操作,从不在反引号中使用find
,使用ls
的方式,因为如果文件名包含,则会失败空格或一些特殊字符,因为shell在空格中分割`command`
的输出,然后对结果字进行通配。相反,请使用-exec
选项find
; ;
版本对每个文件执行mycommand
一次,{}
替换为文件名,而+
版本通常仅使用mycommand
调用{}
一次}替换为文件名列表。
find . -name 'tmp.*' -daystart -mtime 7 -exec mycommand -myoption {} \;
find . -name 'tmp.*' -daystart -mtime 7 -exec mycommand -myoption {} +