我有下面的脚本使用 printf 进行格式化来打印从第一列到第九列的所有指定列,但是我想打印第九列之后的任何列,并且我不确定如何执行此操作
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
它应该打印九个偶数文件或之后分割的名称之后的所有列。
答案1
我发现这是一个有趣的问题,主要是作为学习 awk 的机会。
解析ls稳健地是棘手的并且不推荐,所以我不会在这里详细介绍这些细节。如果您的文件名从不包含任何换行符,那么您可以使用以下 awk 脚本来完成您在单独的部分中所做的所有工作:
- 找出“总计”行
- 获取每个字段的长度
- 动态格式化列
...所有这些都无需多次调用 ls、grep、awk、sort、tail 和 wc,和无需使用eval
.
由于默认ls
列出当前目录 ( ),我也删除了它。pwd
一些随机笔记:
我第一次使用时
awk
没有初始化i
为零,所以我在 BEGIN 块中强制它为零这
grep -v total
部分发生在一行:/^total / { next; }
这实际的解决你的实际的问题是在
for
我们将文件名信息合并到第 9 列 .. NF 的循环中。格式分为两部分:
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 的动态列格式。