【问题标题】:Sort files (including those in subdirectories) based on their size and print file name and size根据文件大小对文件(包括子目录中的文件)进行排序并打印文件名和大小
【发布时间】:2018-12-13 17:31:03
【问题描述】:

需要根据文件大小对文件进行排序,只打印大小和文件名(无路径)。

我尝试使用以下命令来实现这一点,

找到 . -type f -exec du -h {} + |排序 -r -h

但是这样打印结果,

6.0K ~/Documents/Folder/B/File2.txt

6.0K ~/Documents/Folder/KK/KB/File12.txt 

4.0K ~/Documents/Folder/A/File1.txt

但我希望输出打印时使用没有目录前缀的文件名,例如,

6.0K File2.txt

6.0K File12.txt

4.0K File1.txt

注意:我的目录中的所有文件名都是唯一的,在我的情况下不会有任何重复的文件名。我不确定如何达到这个结果。有人可以帮我解决这个问题吗?

【问题讨论】:

  • -r 是反向排序,但这与我看到的输出不匹配。另外,你需要-human-readable 格式,还是字节?
  • 感谢您指出@PaulHodges。结果是按降序排列的,但是在这里写的时候,我按升序写错了。我需要输出为human 可读格式...

标签: linux bash shell sh


【解决方案1】:

findprintf 函数可以在搜索时报告文件大小,以及不带路径的名称。如果您愿意,它甚至可以进行各种格式化以支持整齐的列。

find $PWD -printf "%10.10s\t%f\n" | sort -n

%s 是字节。 %k 将以 KB 为单位列出大小。

一切尽在manual page

我知道这与 du -h 的输出不同,抱歉,但您可以通过跳过所有这些进程调用来节省大量时间......

【讨论】:

  • 它在linux 机器上运行良好。但是当我尝试使用我的 mac 时,它会说,find: -printf: unknown primary or operator。关于如何克服这个问题的任何建议?
  • 检查您的版本。你也许可以install a GNU equivalent
【解决方案2】:

您可以尝试使用awk 来完成它:

find . -type f -exec du -h {} + | sort -r -h | awk '{sub(".*\/","",$2)}1'

它只是在/之后保留最后一句话

awk 用空格分隔行,在你的情况下:

$1         $2    

6.0K      ~/Documents/Folder/B/File2.txt

6.0K      ~/Documents/Folder/KK/KB/File12.txt 

4.0K      ~/Documents/Folder/A/File1.tx

因此,当您想保留第一列时,只需将正则表达式 (.*\/) 应用于第二列。该正则表达式匹配到斜线的所有内容,(我使用\/,因为您需要转义/)。然后,我用''替换那个正则表达式匹配(基本上删除它)。

【讨论】:

  • 删除(替换为'')绝对路径,最后部分除外。
  • 明白了!谢谢 :) 最后的1awk {}1 中做了什么?
  • 我用它来打印行
【解决方案3】:

du 命令输出带有 \t,所以你可以在 awk 中使用 2 个分隔符(\t,/

> find . -type f -exec du -h {} + | sort -r -h | awk -F"[\t/]" ' { print $1,$NF } '
4.0K sameer.pkg
0 rem_col_rows.pl
0 rem_col_rows.dat
0 myfile
>

编辑:

以 csv 格式获取...

> find . -type f -exec du -h {} + | sort -r -h | awk -F"[\t/]" ' { print $1,$NF } ' | tr ' ' ',' | tr '\n' ','
4.0K,sameer.pkg,0,skip_lines.txt,0,rem_col_rows.pl,0,rem_col_rows.dat,0,paras.txt,0,myfile,0,foo.yaml2,0,foo.yaml,

EDIT2

find . -type f -exec du -h {} + | sort -r -h | awk -F"[\t/]" ' { print $1,$NF } ' | tr ' ' ',' | tr '\n' ',' | sed 's/,$//g' 

EDIT3

> find . -type f -exec du -h {} + | sort -r -h | awk -F"[\t/]" ' { printf("%s,%s\n",$1,$NF) } '
4.0K,sameer.pkg
0,skip_lines.txt
0,rem_col_rows.pl
0,rem_col_rows.dat
0,paras.txt
0,myfile
0,foo.yaml2
0,foo.yaml
>

【讨论】:

  • 有什么方法可以打印输出,例如4.0K , sameer.pkg0 , rem_col_rows.pl - 所以这也可以导出为 csv..
  • 是的.. 只需使用tr 命令进行管道传输并将\n 转换为逗号
  • 检查我对答案的编辑
  • 使用 EDIT,整个结果将作为单个文件的输出。如何打印而不丢失我们在之前的结果中得到的换行符?
  • 检查我的 EDIT3.. 我刚刚粘贴了我得到的输出.. 你可以用 awk 本身来做..
猜你喜欢
  • 2019-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-18
  • 2023-01-05
  • 1970-01-01
  • 1970-01-01
  • 2015-04-07
相关资源
最近更新 更多