簡體   English   中英

Bash:從ls -l讀取列

[英]Bash: Reading a column from ls -l

對於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
}

任何幫助將不勝感激,謝謝。

如果問題專門用於解析,那么awk可能是一個不錯的選擇(盡管ls輸出難以可靠地解析)。 同樣,如果問題出在使用數組,那么您的解決方案應專注於這些問題。

但是,如果存在問題以鼓勵您學習可用的工具,我建議:

  • stat工具可顯示有關文件的特定信息(包括大小)
  • 排序工具對輸入行進行重新排序
  • 工具打印輸入的第一行和最后一行
  • 而且您的外殼程序還可以執行路徑名擴展,以列出與glob通配符模式(例如* .txt)匹配的文件

想象一個目錄,其中包含各種大小的文件:

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中EVERSE以便與sort -r )。

默認情況下是按字符對字符進行排序,這對於單詞(“ apple”在“ balloon”之前)非常有用,但對數字卻不太好(“ 10”在“ 9”之前)。 你可以激活ňumeric與排序sort -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

使用ls -S按大小排序,通過直通head獲取前五位,通過sed直通將多個空間壓縮為一個,然后通過直通cut以獲取大小和文件名字段。

robert @ habanero:〜/ scripts $ ls -lS | 頭-n 5 | sed -e's / / / g'| 切-d“” -f 5,9

32K xtractCode.pl

29K tmd55.pl

24K tagebuch.pl

14K備份

只需將目錄指定為初始ls參數即可。

如果不使用findlocatedu ,則可以對每個目錄執行以下操作:

    ls -Sl|grep ^\-|head -5|awk '{printf("%s %d\n", $9, $5);}'

它按大小列出所有文件,過濾出目錄,排在前5位,並打印文件名和大小。 在bash中為每個目錄循環包裝。

這將是另一種選擇。 Ctrl + V + I是如何從命令行插入選項卡。

ls -lS dir1 dir2 dir3.. | awk 'BEGIN{print "Size""Ctrl+V+I""Name"}NR <= 6{print $5"Ctrl+V+I"$9}'

如果您無法使用find locatedu ,還是有一個簡單的選項來獲得文件的大小,而不訴諸ls解析:

size=$(wc -c < "$file")

wc足夠聰明,可以檢測STDIN上的文件並調用stat來獲取大小,因此它的運行速度同樣快。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM