是否可以仅使用 ls 实用程序中的选项列出目录中每个文件的文件名和大小?

是否可以仅使用 ls 实用程序中的选项列出目录中每个文件的文件名和大小?

假设我的目录Historic_Documents有以下文件/大小:

  • Declaration_of_Independence.txt342 字节
  • Magna_Carta.txt1580 字节
  • Treaty_of_Versaille.txt752 字节。

是否可以仅使用ls命令来获取以下输出?

342 Declaration_of_Independence.txt
1580 Magna_Carta.txt
752 Treaty_of_Versaille.txt

答案1

如何使用ls -lwhile 循环解析详细列表的输出
我看了看这个问题,觉得这是一件你可以很容易做到的事情寻找

$ find -maxdepth 1 -type f -printf '%s %f\n'

或者

#!/bin/bash
for i in *; do
    stat --format '%s %N' "$i"
done

(%N 将尊重 QUOTING_STYLE 环境变量;默认为“shell-escape”)。

获取大小的唯一方法ls是通过详细列表。通过使用read读取ls输出;在分配给变量之前,单词的前导和尾随空格将被删除,第一个单词分配给第一个变量,依此类推,当所有变量都分配后,剩余的单词将添加到最后一个变量,这样我们就可以 保存文件名上有空格。

#!/bin/bash
while read -r p c u g s e n; do
    [[ $p = total ]] && continue || { echo -n "$s "; eval "ls -d $n"; }
done < <(ls -Lpl --time-style=+%s --quoting-style=shell-escape)

(使用echo -n "$s "; eval "ls -d $n"有点多余,但它展示了如何将“shell-escape”与其他命令一起使用。如果您只想显示大小和名称的输出,请使用 echo "$s $n"

读取变量:

-rwxr-xr-x 1 bac0n bac0n 209 1572207800 script.sh
     ^     ^   ^     ^    ^      ^         ^
     p     c   u     g    s      e         n

ls选项:

  • -L显示符号链接的文件信息时,显示链接引用的文件的信息而不是链接本身的信息。
  • -p将 / 指示符附加到目录。
  • -l使用长列表格式。
  • --time-style使用 -l 的时间/日期格式;在脚本中将其设置为纪元是一种很好的做法。
  • --quoting-style使用 POSIX 建议的 '$''' 语法引用不可打印字符。

测试目录:

$ ls
a  'b'$'\r''c'   'd'$'\n''e'  "f'g"   h,i  'j k'  'l  m'  'n  '  '  o'

答案2

仅使用ls选项,您就可以执行以下操作:

ls -sd --block-size=1 --format=single-column *

以下是选项:

  • -sd说打印分配的文件大小在块中,该d选项从输出中删除目录“总计”行

  • --block-size=1每单位大小打印 1 个字节(而不是 K)

  • --format=single-column说将结果打印为单列

  • *表示在当前目录中的所有文件上运行,并且在使用该选项ls时需要d

假设您当前的目录是Historic_Documents


编辑:

因为你想要文件内容的大小,所以我认为你不能只用ls选项来做到这一点。但是,你可以使用它du来获得你想要的精确结果:

du -b *

-b或选项--bytes以字节为单位打印实际文件大小,这也相当于选项:--apparent-size --block-size=1

表观大小是文件的大小(类似于列出的大小ls -l),而不是分配的文件大小或磁盘使用情况。

答案3

仅使用ls,没有,但是使用 stat(如果您有lsstat

stat -c "%s %n" *
  • stat使用格式(-c, --format)是获取文件数据最灵活的方式
  • 虽然手册页中没有明确说明,但您可以在字段上使用宽度和精度说明符,例如在 8 列上列出大小:

    stat -c "%8s %n" *
    

答案4

更新 2

下面是使用 的单行代码awk,它的好处是还可以保留文件名中的多个连续空格:

ls -l | awk 'BEGIN{FPAT="([[:space:]]*[^[:space:]]+)"; OFS = "";} FNR == 1 {next} {$1=$2=$3=$4=$6=$7=$8=""}1'
  • FPAT="([[:space:]]*[^[:space:]]+)"用于设置字段应为的正则表达式。在这里,我们将字段设置为包含零个或多个空格字符,以及除空格之外的所有其他字符。关于使用的建议FPAT可以在这个 Stack Overflow 上的答案

  • OFS = ""用来使得输出只有一个空格作为字段分隔符(另一个空格由文本操作添加)。

  • FNR == 1 {next}ls -l这样做的目的是,不会打印开头的空白行(对应于显示已使用块总数的输出的第一行) 。

  • {$1=$2=$3=$4=$6=$7=$8=""}1清空指定的字段并打印其余部分,即第五个字段(文件大小)和第九个直到最后(文件名)。

需要注意的是,上述命令输出的每一行都会有一个或多个前导空格。在我看来,这会使输出更易于阅读,但是,您可以通过将命令传输awksed以下命令来删除前导空格(*从命令中删除sed以仅删除一个前导空格):

ls -l | awk 'BEGIN{FPAT="([[:space:]]*[^[:space:]]+)"; OFS = "";} FNR == 1 {next} {$1=$2=$3=$4=$6=$7=$8=""}1' | sed 's/^ *//'

更新

更好的方法是cut在输出上使用ls -l

ls -l | tr -s ' ' | cut -d ' ' -f 5,9-

这里,tr -s ' '用于将ls -l输出的字段之间的多个空格压缩为一个,然后cut使用空格作为分隔符来显示输出的第五个字段(文件大小)和第九个字段(文件名)之后的所有字段ls -l

但请注意,如果您的文件名包含多个连续的空格,它们将显示为单个空格,因为tr谢谢 bac0n)。


你可以使用这个:

ls -sh
  • -s(或--size):以块为单位打印每个文件的分配大小。
  • -h(或--human-readable)以人类可读的格式打印大小(即分别使用 K、M 等表示千、百万等)。

您可以通过在终端中ls运行或访问来阅读手册页以获取更多信息man lsUbuntuls在线手册页

相关内容