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

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

我的目标看似简单(至少对我来说)。我希望获取ls -l或的输出ls -lh并仅选择一个字段。

我希望它尽可能地坚固,我的意思是假设文件名可以有可变数量的空格,字段中的所有内容并非都具有相同的长度,等等。

如果有一个脚本可以获取字段的名称(或者只是字段编号),然后返回该字段的内容,则可以获得加分。

我想转身

在此处输入图片描述

进入:

在此处输入图片描述

答案1

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

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

答案2

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

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

要逐行读取文件名列表以外的数据并拆分为字段,请参阅:Bash常见问题/001

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

答案3

你可以像下面这样获取 shell 中的特定列:

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

awk如图所示@Corey 回答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

值得注意的是,GNUstat可能与 BSD 有不同的选择stat,因此它仍然不能跨不同的操作系统做到万无一失。

答案4

我需要在备份和升级之前对我安装的应用程序进行分类,并在尝试弄清楚如何修剪ls输出时遇到了这个问题,但是awk其他 Ask Ubuntu 问题中建议的应用程序根本不起作用。

对我有用的是使用的建议cut:我将 test ls 输出重定向到文本文件,并使用 Sumblime Text 中的“标尺”来查找字符列号

total 2060
         1         2         3         4         5
123456789012345678901234567890123456789012345678901234567890
-rw-r--r-- 1 root    root      291 2023-04-12 13:53 apport-gtk.desktop
-rw-r--r-- 1 root    root      277 2023-04-12 13:53 apport-kde-mime.desktop
-rw-r--r-- 1 root    root     3417 2018-04-14 03:38 assistant-qt5.desktop
-rw-r--r-- 1 root    root     1066 2022-03-07 19:03 atom.desktop
-rw-r--r-- 1 root    root     2683 2018-05-01 04:10 audio-recorder.desktop
...

然后用 cut -c30- 进行过滤,其中尾随连字符将渲染延伸到(可变长度)行的末尾。

$ dir -l --time-style=long-iso /usr/share/applications | cut -c30-

  291 2023-04-12 13:53 apport-gtk.desktop
  277 2023-04-12 13:53 apport-kde-mime.desktop
 3417 2018-04-14 03:38 assistant-qt5.desktop
 1066 2022-03-07 19:03 atom.desktop
 2683 2018-05-01 04:10 audio-recorder.desktop
...

由于 的字段对齐在第一个访问权限字段之后是相对的,因此需要进行此“标尺检查” ls。对于此处的具体问题(隔离月份中的日期),我们可以将第 38 列和第 39 列确定为我们的目标。

$ ls -l >> cutcheck.txt
$ cat cutcheck.txt
         1         2         3         4         5
123456789012345678901234567890123456789012345678901234567890
total 480
-rwxrwx--- 1 root plugdev    112 Mar 12 17:36 cutcheck.txt
-rwxrwx--- 1 root plugdev    112 Mar 12 17:34 cutruler.txt
drwxrwx--- 3 root plugdev  32768 Mar 10 17:53 KDEAppLaucherConfig
-rwxrwx--- 1 root plugdev 195385 Mar  2 18:02 KDEAppLaucherMenuEditorHandbk.pdf
-rwxrwx--- 1 root plugdev   2202 Mar 11 18:30 KDEAppLauncherFiles.txt
-rwxrwx--- 1 root plugdev  40346 Mar  5 21:10 KDEApps.ods
-rwxrwx--- 1 root plugdev  90993 Mar  5 20:12 KDEMenuAppsDesktopFiles.html
$ ls -l | cut -c38-39

12
12
10
 2
11
 5
 5

一旦您知道特定文件系统的“大致”字符列值,您就可以发出连续的cut命令来隔离您需要提取的内容。

stat命令允许指定特定的ls/dir输出字段,但ls由于字段长度可变,整齐的列对齐会丢失。awk@Corey Whitaker 的答案中给出的应用程序确实有效,但同样会丢失列对齐。

stat如果目的是直接导入电子表格目录,我认为这是更好的选择,因为字段代码可以用逗号分隔,以便重定向到 CSV 文件。

相关内容