我想漂亮地打印类似于find的脚本的输出,这些脚本将采用如下输入:
- 2015-10-02 19:45 102 /My Directory/some file.txt
并产生类似的东西:
- 102 /My Directory/some file.txt
换句话说:“f”(对于“文件”),文件大小(右对齐),然后是路径名(具有任意数量的空格)。
如果我能编写一个花费1美元,4美元和“从5美元到行尾的所有内容”的脚本,这在awk中很容易。
我尝试使用awk构造substr($ 0,index($ 0,$ 8)),我认为意味着“一切从字段$ 8开始到$ 0结尾”。
以这种方式使用index()作为linuxquestions.org上的解决方案提供,并在stackoverflow.com线程中被投票了29次。
然而,仔细观察,我发现如果起始字段恰好匹配字符串中的较早点,则index()不会达到此效果。例如,给定:
-rw-r--r-- 1 tbaker staff 3024 2015-10-01 14:39 calendar
-rw-r--r-- 1 tbaker staff 4062 2015-10-01 14:39 b
-rw-r--r-- 1 tbaker staff 2374 2015-10-01 14:39 now or later
Gawk(和awk)获得以下结果:
$ gawk '{ print index($0, $8) }' test.txt
49
15
49
换句话说,$ 8('b')的值匹配索引15而不是49(即,与大多数其他文件名一样)。
我的问题是如何指定“从字段X到字符串末尾的所有内容”。
我已经重写了这个问题,以便明确这一点。
答案 0 :(得分:1)
在我看来你应该只使用" stat"命令而不是" ls",由于已经评论过的原因:
stat -c "f%15s %n" *
但你应该仔细检查你的" stat"操作;它显然可以是特定于shell的。
答案 1 :(得分:0)
有时建议使用内置的awk函数index()作为一种方法 打印“从字段5到字符串末尾”[1,2,3]。
在awk中,索引($ 0,$ 8)不表示“第一个字符的索引” 字符串$ 0中的字段8“。相反,它表示”第一次出现的索引 字符串$ 0的字符串值8“。在许多情况下,第一个 发生将确实是第8场中的第一个字符,但这不是 上例中的情况。
有人指出,解析ls
的输出通常是不好的
想法[4],部分原因是ls
的实现在输出方面存在显着差异。
由于该说明的作者建议将find
替换为某些用途的ls
,
这是一个使用find的脚本:
find $@ -ls |
sed -e 's/^ *//' -e 's/ */ /g' -e 's/ /|/2' -e 's/ /|/2' -e 's/ /|/4' -e 's/ /|/4' -e 's/ /|/6' |
gawk -F'|' '{ $2 = substr($2, 1, 1) ; gsub(/^-/, "f", $2) }
{ printf("%s %15s %s\n", $2, $4, $6) }'
...产生所需的输出:
f 4639 /Users/foobar/uu/a
f 3024 /Users/foobar/uu/calendar
f 2374 /Users/foobar/uu/xpect
这种方法以递归方式遍历文件树。但是,find
的版本之间当然也可能存在实现差异。
答案 2 :(得分:0)
也许你正在寻找find -printf | awk
的某些变体?
$ ls -l tmp
total 2
-rw-r--r-- 1 Ed None 7 Oct 2 14:35 bar
-rw-r--r-- 1 Ed None 2 Oct 2 14:35 foo
-rw-r--r-- 1 Ed None 0 May 3 09:55 foo bar
$ find tmp -type f -printf "f %s %p\n" | awk '{sub(/^[^ ]+ +[^ ]/,sprintf("%s %10d",$1,$2))}1'
f 7 tmp/bar
f 2 tmp/foo
f 0 tmp/foo bar
或
$ find tmp -type f -printf "%s %p\n" | awk '{sub(/^[^ ]+/,sprintf("f %10d",$1))}1'
f 7 tmp/bar
f 2 tmp/foo
f 0 tmp/foo bar
它不适用于包含换行符的文件名。