对于uni的问题,我需要获取一系列目录中5个最大文件的文件大小和文件名。要做到这一点,我正在使用两个函数,一个用ls -l加载所有东西(我意识到从ls解析信息不是一个好方法,但这个特殊问题指明我不能使用find,locate或du) 。然后将来自ls输出的每一行发送到另一个函数,该函数使用awk应该撤销文件大小和文件名并将其存储到数组中。相反,我似乎正在尝试打开ls中的每一列来阅读。 这样的代码如下:
function addFileSize {
local y=0
local curLine=$1
if [[ -z "${sizeArray[0]}" ]]; then
i=$(awk '{print $5}' $curLine)
nameArray[y]=$(awk '{print $9}' $curLine)
elif [[ -z "${sizeArray[1]}" ]]; then
i=$(awk '{print $5}' $curLine)
nameArray[y]=$(awk '{print $9}' $curLine)
elif [[ -z "${sizeArray[2]}" ]]; then
i=$(awk '{print $5}' $curLine)
nameArray[y]=$(awk '{print $9}' $curLine)
elif [[ -z "${sizeArray[3]}" ]]; then
i=$(awk '{print $5}' $curLine)
nameArray[y]=$(awk '{print $9}' $curLine)
elif [[ -z "${sizeArray[4]}" ]]; then
i=$(awk '{print $5}' $curLine)
nameArray[y]=$(awk '{print $9}' $curLine)
fi
for i in "${sizeArray[@]}"; do
echo "$(awk '{print $5}' $curLine)"
if [[ -z "$i" ]]; then
i=$(awk '{print $5}' $curLine)
nameArray[y]=$(awk '{print $9}' $curLine)
break
elif [[ $i -lt $(awk '{print $5}' $curLine) ]]; then
i=$(awk '{print $5}' $curLine)
nameArray[y]=$(awk '{print $9}' $curLine)
break
fi
let "y++"
done
echo "Name Array:"
echo "${nameArray[@]}"
echo "Size Array:"
echo "${sizeArray[@]}"
}
function searchFiles {
local curdir=$1
for i in $( ls -C -l -A $curdir | grep -v ^d | grep -v ^total ); do # Searches through all files in the current directory
if [[ -z "${sizeArray[4]}" ]]; then
addFileSize $i
elif [[ ${sizeArray[4]} -lt $(awk '{print $5}' $i) ]]; then
addFileSize $i
fi
done
}
非常感谢任何帮助,谢谢。
答案 0 :(得分:2)
如果问题特别是关于解析,那么awk可能是一个不错的选择(虽然ls
输出很难可靠解析)。同样,如果问题是关于使用数组,那么您的解决方案应该关注那些。
但是,如果问题是鼓励您了解可用的工具,我建议:
想象一个包含各种大小文件的目录:
10000000 sound/concert.wav 1000000 sound/song.wav 100000 sound/ding.wav
您可以使用路径名扩展查找其名称:
$ echo sound/*
sound/concert.wav sound/ding.wav sound/song.wav
您可以使用 stat 将名称转换为si z e:
$ stat -f 'This one is %z bytes long.' sound/ding.wav
This one is 100000 bytes long.
与大多数Unix工具一样,无论您提供一个或多个参数,stat
的工作方式都相同:
$ stat -f 'This one is %z bytes long.' sound/concert.wav sound/ding.wav sound/song.wav
This one is 10000000 bytes long.
This one is 100000 bytes long.
This one is 1000000 bytes long.
(查看man stat
以获取有关%z
的参考信息以及您可以打印的其他内容。文件的 N ame特别有用。)
现在你有一个文件大小列表(希望你也保留了他们的名字)。你如何找到最大的尺寸?
在排序列表中找到最大项目要比未排序列表容易得多。要了解它,请考虑如何在此未排序列表中找到最高的两项:
1234 5325 3243 4389 5894 245 2004 45901 3940 3255
如果对列表进行排序,您可以非常快速地找到最大的项目:
245 1234 2004 3243 3255 3940 4389 5325 5894 45901
Unix 排序实用程序接受输入行并从最低到最高输出(或以 r 顺序输出sort -r
)。
它默认按字符排序,这对于单词很有用(“apple”在“气球”之前出现)但对数字来说不是很好(“10”在“9”之前出现)。您可以使用sort -n
激活 n 数字排序。
一旦您有一个排序的行列表,您可以使用 head 工具打印第一行,或使用 tail 工具打印最后一行。
拼写检查的(已经排序的)单词列表的前两项:
$ head -n 2 /usr/share/dict/words
A
a
最后两项:
$ tail -n 2 /usr/share/dict/words
Zyzomys
Zyzzogeton
通过这些部分,您可以组合问题的解决方案“找到dir1,dir2,dir3中的五个最大的文件”:
stat -f '%z %N' dir1/* dir2/* dir3/* |
sort -n |
tail -n 5
或者“找到dir1,dir,dir3,dir4,dir5中每个文件中最大的文件”的解决方案:
for dir in dir1 dir2 dir3 dir4 dir5; do
stat -f '%z %N' "$dir"/* |
sort -n |
tail -n 1
done
答案 1 :(得分:0)
使用ls -S
按大小排序,通过head
进行排序以获得前五名,通过sed
管道将多个空格压缩为一个,然后通过cut
管道输入获取大小和文件名字段。
罗伯特@哈瓦那:〜/ scripts $ ls -lS |头-n 5 | sed -e's / / / g'| cut -d“” - f 5,932K xtractCode.pl
29K tmd55.pl
24K tagebuch.pl
14K备份
只需将目录指定为初始ls
的参数。
答案 2 :(得分:0)
不使用find
,locate
或du
,您可以为每个目录执行以下操作:
ls -Sl|grep ^\-|head -5|awk '{printf("%s %d\n", $9, $5);}'
按大小列出所有文件,过滤掉目录,占据前5位,并打印文件名和大小。在每个目录的bash中使用循环包装。
答案 3 :(得分:0)
这将是另一种选择。 Ctrl + V + I是如何从命令行插入选项卡。
ls -lS dir1 dir2 dir3.. | awk 'BEGIN{print "Size""Ctrl+V+I""Name"}NR <= 6{print $5"Ctrl+V+I"$9}'
答案 4 :(得分:0)
如果您无法使用find
locate
和du
,那么仍然可以直接选择获取文件大小而无需求助于ls
解析:
size=$(wc -c < "$file")
wc
非常聪明,能够在STDIN上检测文件并调用stat
来获取大小,因此效果一样快。