【问题标题】:'Total' in ls -lsh in UnixUnix 中 ls -lsh 中的“总计”
【发布时间】:2015-04-02 20:21:37
【问题描述】:

我正在尝试使用 ls -lsh 命令仅将文件大小输出到文件。但它也显示总数。 我需要类似的东西:

。 ./sample.txt 4.0K
./multisample.txt 4.0K

但显示如下
. ./test.txt ./multitest.txt
4.0K
4.0K

.:
总计
4.0K
4.0K
4.0K
我使用的命令是: ls -lsh $LISTNAME |awk '{print $1}' >> /home/test/$date.log
其中$LISTNAME 包含文件名。
请告诉我如何只显示文件大小以及我需要的格式(文件名1 tab 文件大小和下一行文件名2 tab 文件大小)

【问题讨论】:

  • 您知道文件名可以包含制表符吗?
  • 坦率地说,最可靠/错误最少的方法是不用自己编写代码来将数字更改为人类可读的值(我过去就是这样做的)是一个单独的du -sh 每个输入文件调用,然后只提取输出的大小部分。它既混乱又低效,但它使您摆脱了解析文件名的工作。 (此外,现代 GNU du 支持 -0 参数,这有助于消除歧义)。

标签: linux bash unix awk ls


【解决方案1】:

Don't parse ls.

最好的方法是:

# this assumes your filenames don't contain whitespace
stat -c $'%n\t%s' $LISTNAME

如果 $LISTNAME 是一个以换行符分隔的文件列表,这将容纳文件名中的空格和/或制表符,但不容纳换行符。假设 bash(我认为是第 4 版)

mapfile -t files <<<"$LISTNAME"
stat -c $'%n\t%s' "${files[@]}"

【讨论】:

  • 它只是将文件大小显示为数字。我需要有 5K 或 5G 之类的东西。以上命令输出为: ./test.txt 4 ./multitest.txt 5
【解决方案2】:

如果您理解并接受如果任何文件名包含任何空白字符,这将中断,则此命令会执行您尝试执行的操作:

ls -1sh | awk '!/^total / { print $2 "\t" $1 }'

如果您需要处理包含空格的文件名,您可能会更乐意编写使用 OS 原语列出目录并获取每个文件大小的 perl 或 python 脚本。

【讨论】:

  • 如果我使用上面的命令,它给出的输出为: ./test.txt 4.0K ./multitest.txt 4.0K .: ./test.txt 4.0K ./multitest.txt 4.0K -- > 显示两次。请帮我解决这个问题。
  • 请提出一个新问题。
  • 我已将此问题包含在我的问题中。请告诉我如何消除这些重复项。
  • 请提出一个关于重复项的问题。
【解决方案3】:

假设 bash(不是 /bin/sh)和 GNU du

# Collect a list of files (not directories, to prevent recursion)
files=( ); for f in *; do [[ -f "$f" ]] && files+=( "$f" ); done

while IFS= read -r -d '' line; do
  filename=${line#*$'\t'}
  size=${line%%$'\t'*}
  printf '%q\t%s\n' "$filename" "$size"
done < <(du -0sh --apparent-size "${files[@]}")

因为它使用printf %q,它会以明确的、eval 安全的形式写入带有空格、制表符甚至换行符的文件名。例如:

CHECKSUMS       4.0K
exit-trap       4.0K
$'file with a tab here:\t and a newline here:\n'        1.0K

...如果您想直接写这些字符(对明确解析文件内容的能力有明显影响),只需将%q 替换为%s

【讨论】:

    【解决方案4】:

    试试这个:

    ls -lh | awk '{print $9 "\t" $5}'
    

    【讨论】:

    • ls -l 的标准不保证在读取以空格分隔的输出时,超过时间的任何列都将位于特定位置。此外,$9 在此用法中无法正确处理带有空格的名称。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-04
    • 2013-08-15
    • 1970-01-01
    • 2015-10-28
    • 2016-09-07
    • 2015-06-10
    相关资源
    最近更新 更多