如何从“ ls -l”的输出中选择一个字段/列?


22

我的目标看似简单(至少对我而言)。我希望采用ls -l或的输出,ls -lh并仅选择一个字段。

我希望这尽可能地防弹,也就是说,假设文件名可以具有可变数量的空格,而不是字段中的所有内容都具有相同的长度,等等。

拥有一个使用字段名称(甚至是字段编号)然后返回字段内容的脚本的好处是。

我想转身

在此处输入图片说明

变成:

在此处输入图片说明

Answers:


41

尝试ls -l | awk '{print $7}'

awk 选择列,因此非常适合此任务。


3
正如@ormaaj所解释的:不要依赖于特定位置可用的信息ls。该find命令非常有用。
帕迪·兰道

@PaddyLandau如何使用find命令像可以打印那样以兆字节为单位打印文件大小ls -l --block-size=M
SurpriseDog

@Benjamin —该ls命令不是POSIX标准,因此依赖的脚本ls可能会在不同系统上甚至随着时间的流逝而中断。有关更多详细信息,请参阅此页面上@ormaaj的答案。一种执行要求的方法是使用Bash循环。这是一个例子。for FILENAME in *; do FILESIZE=$(( $( stat --format=%s "${FILENAME}" ) / 1024 )); echo "${FILENAME}" ${FILESIZE}; done。当然echo,您可以使用处理来代替。
帕迪兰道

@PaddyLandau我刚刚结束了将find命令的输出传递到管道的工作,该命令也... | xargs -d '\n' du -m可以正常工作。
SurpriseDog

@Benjamin您可能想看看的-exec选项find
帕迪兰道

17

永不解析ls。使用GNU find。或者,如果可移植性不重要,则stat(1)

find . -maxdepth 1 -printf '%Td\n'

有关逐行读取文件名列表以外的数据并拆分为字段的信息,请参阅:BashFAQ / 001

在大多数情况下,没有方法可以可靠地读取以换行符分隔的文件名列表。


1

您可以像这样在shell中获取特定的列:

ls -al | while read perm bsize user group size month day time file; do echo $day; done

awk@Corey answer中所示,cut -c44-45也可以在调整后(因为ls具有固定的列)或其他任何方法,但是主要的问题是它不可靠且不易受攻击(例如,在Unix上可能是$6,不是$7,并且更改取决于参数),使其对机器不友好,因此不建议完全解析ls命令

最好是使用不同的可用命令,例如findstat,这些命令可以提供相关选项来根据需要格式化输出。例如:

$ stat -c "%x %n" *
2016-04-10 04:53:07.000000000 +0100 001.txt
2016-04-10 05:08:42.000000000 +0100 7c1c.txt

要返回仅几天修改的列,请尝试以下示例:

stat -c "%x" * | while read ymd; do date --date="$ymd" "+%d"; done

值得注意的是,GNU stat对于BSD可能有不同的选择stat,因此它在不同的操作系统上仍然不是安全的。


1
+1提到,LS不应该被解析,以及使用的statdate但是设置不正确。您应该添加--date=$ymd,因为date它本身会打印当天的日期,但是这里的目的是转换文件的日期格式
Sergiy Kolodyazhnyy

ls -la | cut -c32-33完全诚实的命令是完全不可靠的,不仅因为文件名可能存在陷阱,还因为它取决于用户名的长度和文件的大小。该stat -c "%x" *.*命令看起来不错,但是通过使用*.*它只能将其限制为包含点的文件名。我想本来是要捕获隐藏文件的。在这种情况下,您应该事先为点文件启用全局切换并使用*代替*.*shopt -s dotglob; stat -c "%x" * | [...]
kos

嗯,什么SERG也说,你应该添加--date="$ymd"date命令,否则将打印该月的当前日期。
kos

感谢您的评论。我已经解决了这些问题,并提供了一个更好的初始示例。
kenorb '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.