gpt4 book ai didi

linux - Bash:从 ls -l 读取专栏

转载 作者:太空宇宙 更新时间:2023-11-04 09:27:33 25 4
gpt4 key购买 nike

对于 uni 的一个问题,我需要获取一系列目录中 5 个最大文件的文件大小和文件名。为此,我使用了两个函数,一个用 ls -l 加载所有内容(我意识到从 ls 解析信息不是一个好方法,但这个特定问题指定我不能使用 find、locate 或 du) .然后将 ls 输出中的每一行发送到另一个函数,该函数使用 awk 应该提取文件大小和文件名并将其存储到一个数组中。相反,我似乎越来越 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
}

非常感谢任何帮助,谢谢。

最佳答案

如果问题专门与解析有关,那么 awk 可能是一个不错的选择(尽管 ls 输出很难可靠地解析)。同样,如果问题与使用数组有关,那么您的解决方案应该专注于这些。

但是,如果问题在于鼓励您学习可用的工具,我建议:

  • stat 工具打印有关文件的特定信息(包括大小)
  • 排序工具重新排序输入行
  • headtail 工具打印输入的第一行和最后一行
  • 并且您的 shell 还可以执行路径名扩展 以列出与 glob 通配符模式匹配的文件,如 *.txt

想象一个包含各种大小文件的目录:

  10000000 sound/concert.wav   1000000 sound/song.wav    100000 sound/ding.wav

You can use pathname expansion to find their names:

$ echo sound/*
sound/concert.wav sound/ding.wav sound/song.wav

您可以使用 stat 将名称转换为 size:

$ 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名称特别有用。)


现在您有了一个文件大小列表(希望您也保留了它们的名称)。如何找到最大的尺寸?

与未排序的列表相比,在排序的列表中找到最大的项目要容易得多。要感受一下,请考虑如何在这个未排序的列表中找到最高的两项:

1234 5325 3243 4389 5894 245 2004 45901 3940 3255

而如果列表已排序,您确实可以很快找到最大的项目:

245 1234 2004 3243 3255 3940 4389 5325 5894 45901

Unix sort 实用程序获取输入行并将它们从最低到最高输出(或者以 rsort -r 相反的顺序) .

它默认按字符排序,这对单词非常有用(“apple”排在“balloon”之前),但对数字就不太好(“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

关于linux - Bash:从 ls -l 读取专栏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34700107/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com