Awk
如何使用格式設置 awk 和 printf 列並包括 9 號之後的所有列
我有下面的腳本來列印從第 1 列到第 9 列的所有指定列,使用 printf 進行格式化,但是我想列印第 9 列之後的任何列,但我不確定該怎麼做
pwd=`pwd` #Megabytes max_size_1=`ls -ltr "$pwd" | grep -v "total" | awk '{print $1}' | sort -n | tail -1 | wc -m` max_size_2=`ls -ltr "$pwd" | grep -v "total" | awk '{print $2}' | sort -n | tail -1 | wc -m` max_size_3=`ls -ltr "$pwd" | grep -v "total" | awk '{print $3}' | sort -n | tail -1 | wc -m` max_size_4=`ls -ltr "$pwd" | grep -v "total" | awk '{print $4}' | sort -n | tail -1 | wc -m` max_size_5=`ls -ltr "$pwd" | grep -v "total" | awk '{$5=sprintf("%.0f M", $5/1024^2)} 1' | awk '{print $5}' | sort -n | tail -1 | wc -m` ls -ltr "$pwd" | grep -v "total" | awk '{$5=sprintf("%.0f M", $5/1024^2)} 1' | eval "awk '{printf \"%$max_size_1-s %$max_size_2-s %$max_size_3-s %$max_size_4-s %$max_size_5-s %-3s %-3s %-3s %-6s\\n\", \$1, \$2, \$3, \$4, \$5, \$6, \$7, \$8, \$9}'"
輸出是:
-rwxr-xr-x 1 informix informix 0 M Mar 1 13:45 -rwxr-xr-x 1 informix informix 0 M Mar 1 13:45 -rwxr-xr-x 1 informix informix 0 M Mar 1 13:46 -rwxr-xr-x 1 informix informix 0 M Mar 9 10:51 -rw-r----- 1 informix informix 0 M Mar 9 12:36 -rwxrwxrwx 1 informix informix 0 M Mar 9 13:01
我想要什麼:
-rwxr-xr-x 1 informix informix 0 M Mar 1 13:45 ls-ltrg -rwxr-xr-x 1 informix informix 0 M Mar 1 13:45 ls-ltrk -rwxr-xr-x 1 informix informix 0 M Mar 1 13:46 ls-ltrb -rwxr-xr-x 1 informix informix 0 M Mar 9 10:51 ls-ltrm -rw-r----- 1 informix informix 0 M Mar 9 12:36 split word -rwxrwxrwx 1 informix informix 0 M Mar 9 13:01 test.sh
它應該列印九個偶數文件或此後拆分的名稱之後的所有列。
我發現這是一個有趣的問題,主要是作為 awk 的學習機會。
穩健地解析 ls很棘手,不推薦,所以我不會在這裡討論這些細節。如果您的文件名從不包含任何換行符,那麼您可以使用以下 awk 腳本來完成您在單獨的部分中所做的所有工作:
- 找出“總”行
- 獲取每個欄位的長度
- 動態格式化列
… 無需多次呼叫 ls、grep、awk、sort、tail 和 wc,也無需使用
eval
.由於預設
ls
列出目前目錄 (pwd
),因此我也將其刪除。一些隨機筆記:
- 我在第一次使用
awk
時沒有初始化i
為零,所以我在 BEGIN 塊中將其強制為零- 該
grep -v total
部分發生在一行中:/^total / { next; }
- 您的實際問題的實際解決方案是在循環中,我們在第 9 列中合併文件名資訊 .. NF。
for
- 格式分為兩部分:
for
END 塊中的第一個循環確定我們需要的寬度;第二個for
循環使用*
格式說明符來完成真正的工作——通過在實際值之前傳遞所需的寬度。這是生成的腳本/程式碼:
ls -ltr | awk ' BEGIN { i=0; } /^total / { next; } { perms[i]=$1 links[i]=$2 owner[i]=$3 group[i]=$4 $5=sprintf("%.0f M", $5/1024^2) size[i]=$5 date[i]=$6 " " $7 " " $8 for(x=9; x <= NF; x++) name[i] = name[i] " " $x i++ } END { for(j=0;j<i;j++) { if (length(perms[j]) > maxperms) maxperms = length(perms[j]) if (length(links[j]) > maxlinks) maxlinks = length(links[j]) if (length(owner[j]) > maxowner) maxowner = length(owner[j]) if (length(group[j]) > maxgroup) maxgroup = length(group[j]) if (length(size[j]) > maxsize) maxsize = length(size[j]) } for(j=0;j<i;j++) { printf "%-*s %-*s %-*s %-*s %-*s %s %s\n", maxperms, perms[j], maxlinks, links[j], maxowner, owner[j], maxgroup, group[j], maxsize, size[j], date[j], name[j] } } '
非常感謝 G-Man,他提供了現成的備忘單供我用於awk 的動態列格式化。