如何更改 awk 脚本以在 Solaris 上工作
How to change an awk script to work on Solaris
下面的脚本是 bin-packing First-fit 算法,脚本在 ubuntu Linux 上正常 运行ning 并且我可以调用 bin_packing.awk,但是当我尝试 运行 它在 unix solaris 上我遇到错误
bin_packing.awk
:
function first_fit(v, file) {
# find first bin that can accomodate the volume
for (i=1; i<=n; ++i) {
if (b[i] > v) {
b[i] -= v
bc[i]++
cmd="mv "file" subdir_" i
print cmd
# system(cmd)
return
}
}
# no bin found, create new bin
if (i > n) {
b[++n] = c - v
bc[n]++
cmd="mkdir subdir_"n
print cmd
# system(cmd)
cmd="mv "file" subdir_"n
print cmd
# system(cmd)
}
return
}
BEGIN{ if( (c+0) == 0) exit }
{ first_fit(,) }
END { print "REPORT:"
print "Created",n,"directories"
for(i=1;i<=n;++i) print "- subdir_"i,":", c-b[i],"bytes",bc[i],"files"
}
并调用它:
$ find . -type f -iname '*pdf' -printf "%s %p\n" \
| awk -v c=100000 -f bin_packing.awk
这将创建一个文件列表,其前面的文件大小以字节为单位。值 c 是目录可以具有的最大大小(以字节为单位)。上面的值 c=100000 只是一个例子,这将创建如下输出:
...
mv file_47 subdir_6
mv file_48 subdir_6
mv file_49 subdir_5
mv file_50 subdir_6
REPORT:
Created 6 directories
- subdir_1 : 49 bytes 12 files
- subdir_2 : 49 bytes 9 files
- subdir_3 : 49 bytes 8 files
- subdir_4 : 49 bytes 8 files
- subdir_5 : 48 bytes 8 files
- subdir_6 : 37 bytes 5 files
如果我尝试在 Solaris 上 运行 它会显示以下错误,并且根据反馈-printf 是 GNU 功能,因此它在非 GNU 版本的 find[=16 中不可用=]
find: bad option -printf
find: [-H | -L] path-list predicate-list
awk: syntax error near line 1
awk: bailing out near line 1
在 Solaris 中使用 nawk
(新 awk)或 /usr/xpg4/bin/awk
(POSIX awk)。 awk
是 Perl 的原始遗留版本,用于收集与 find 的 -printf:
相同的信息
解决方法如下:
$ find . -type f -name '*.pdf' -print | perl -lne '$,=" "; @s=stat $_; print $s[7],$_, $s[2]' | nawk -v c=5000000 -f bin_packing.awk
要解决缺少 --printf 查找功能的问题,您可以尝试:
find . -type f -iname '*pdf' -exec stat --printf="%s %n\n" {} \; \
| awk -v c=100000 -f bin_packing.awk
下面的脚本是 bin-packing First-fit 算法,脚本在 ubuntu Linux 上正常 运行ning 并且我可以调用 bin_packing.awk,但是当我尝试 运行 它在 unix solaris 上我遇到错误
bin_packing.awk
:
function first_fit(v, file) {
# find first bin that can accomodate the volume
for (i=1; i<=n; ++i) {
if (b[i] > v) {
b[i] -= v
bc[i]++
cmd="mv "file" subdir_" i
print cmd
# system(cmd)
return
}
}
# no bin found, create new bin
if (i > n) {
b[++n] = c - v
bc[n]++
cmd="mkdir subdir_"n
print cmd
# system(cmd)
cmd="mv "file" subdir_"n
print cmd
# system(cmd)
}
return
}
BEGIN{ if( (c+0) == 0) exit }
{ first_fit(,) }
END { print "REPORT:"
print "Created",n,"directories"
for(i=1;i<=n;++i) print "- subdir_"i,":", c-b[i],"bytes",bc[i],"files"
}
并调用它:
$ find . -type f -iname '*pdf' -printf "%s %p\n" \
| awk -v c=100000 -f bin_packing.awk
这将创建一个文件列表,其前面的文件大小以字节为单位。值 c 是目录可以具有的最大大小(以字节为单位)。上面的值 c=100000 只是一个例子,这将创建如下输出:
...
mv file_47 subdir_6
mv file_48 subdir_6
mv file_49 subdir_5
mv file_50 subdir_6
REPORT:
Created 6 directories
- subdir_1 : 49 bytes 12 files
- subdir_2 : 49 bytes 9 files
- subdir_3 : 49 bytes 8 files
- subdir_4 : 49 bytes 8 files
- subdir_5 : 48 bytes 8 files
- subdir_6 : 37 bytes 5 files
如果我尝试在 Solaris 上 运行 它会显示以下错误,并且根据反馈-printf 是 GNU 功能,因此它在非 GNU 版本的 find[=16 中不可用=]
find: bad option -printf find: [-H | -L] path-list predicate-list awk: syntax error near line 1 awk: bailing out near line 1
在 Solaris 中使用 nawk
(新 awk)或 /usr/xpg4/bin/awk
(POSIX awk)。 awk
是 Perl 的原始遗留版本,用于收集与 find 的 -printf:
解决方法如下:
$ find . -type f -name '*.pdf' -print | perl -lne '$,=" "; @s=stat $_; print $s[7],$_, $s[2]' | nawk -v c=5000000 -f bin_packing.awk
要解决缺少 --printf 查找功能的问题,您可以尝试:
find . -type f -iname '*pdf' -exec stat --printf="%s %n\n" {} \; \
| awk -v c=100000 -f bin_packing.awk