在bash中更改find-printf的值
我正在使用find为每个文件和目录打印一行:在bash中更改find-printf的值,bash,awk,find,printf,Bash,Awk,Find,Printf,我正在使用find为每个文件和目录打印一行: find ${rootdirectory} -printf '%p,%T@\n' >> ${outputfile} 但是,我喜欢将unixepoch的%T@转换为Windows FILETIME: filetime=$(( (%T@ + 11644473600) * 10000000 )) find ${rootdirectory} -printf '%p,${filetime}\n' >> ${outputfile} 这
find ${rootdirectory} -printf '%p,%T@\n' >> ${outputfile}
但是,我喜欢将unixepoch的%T@
转换为Windows FILETIME:
filetime=$(( (%T@ + 11644473600) * 10000000 ))
find ${rootdirectory} -printf '%p,${filetime}\n' >> ${outputfile}
这当然不起作用,因为在find-printf
之前没有设置%t@
更改找到的整数时,查找数百万个文件的最快方法是什么?我已经有了一个使用stat
的解决方案,但速度非常慢:
find ${rootdirectory} -exec 1>${outputfile} sh -c 'for file in "${1}"/* ;
do
unixtime=$(stat -c%Y ${file})
filetime=$(( (${unixtime} + 11644473600) * 10000000 ))
stat -c%n,${filetime} ${file}
done' none {} \;
我用-printf
将其更改为变体,但无法识别T
:
find ${rootdirectory} -exec 1>${outputfile} sh -c 'for file in "${1}"/* ;
do
unixtime=$(printf %T@)
filetime=$(( (${unixtime} + 11644473600) * 10000000 ))
-printf %p,${filetime}
done' none {} \;
我最后的希望是:
print_format="%p,$(( %T@ + 11644473600 ))\n"
find ${rootdirectory} -printf "$print_format"
为了完整起见,这不起作用:
find ${rootdirectory} -printf '%p,$(( (%T@ + 11644473600) * 10000000 ))\n'
有人有什么想法吗?而且
xargs
会比exec
快吗?解决方案中的“杀手”是“shell”的重复执行(每个文件一个)。正如您已经指出的,“find”不支持运算符上的算术运算
一种替代方法是使用后处理器(awk、Perl、Python),从find读取输出并执行转换
# Using printf
find ${rootdirectory} -printf '%p,%T@\n' | awk -v FS=, -v OFS=, '{ printf ("%s,%d\n", $1, ($2+ 11644473600) * 10000000)}'
# On 32 bit environment, using %.0f
find ${rootdirectory} -printf '%p,%T@\n' | awk -v FS=, -v OFS=, '{ printf ("%s,%.0f\n", $1, ($2+ 11644473600) * 10000000)}'
# Or using regular print
find ${rootdirectory} -printf '%p,%T@\n' | awk -v FS=, -v OFS=, '{ printf ("%s,%d\n", $1, ($2+ 11644473600) * 10000000)}'
只需调用一次awk
,这将比尝试的解决方案快得多
使用xargs可以加快代码的速度,但前提是使用一些“bulking”,其中大量文件将由单个命令处理。它不太可能比“awk”——单个进程更快
使用
bash
唯一的解决方案将很困难,因为bash不支持浮点值的数学运算(在mint19上,@T包括分数)。谢谢!虽然这给了我一个科学的符号。我不得不改用printf
,但添加\n
会让我很难。你把它放在哪里?@kamikater代码修改为使用printf,没有小数。结果总是2147483647
。15721789688001529300
的给定时间应变为132166525688001529,3
,但作为整数132166525688001529
。不需要四舍五入。这是一个awk
问题,我现在都是小sed
。2147483647似乎是32/64位问题。在我的机器上(64位),我得到132165795920421120或类似的数据。使用“%.0f”可以解决32位上的问题。见上面代码的第二行,就是这样!谢谢@dash-o:)我现在几乎没有什么awk
。如果你能告诉我为什么这不起作用,我们将非常感激:find${rootdirectory}-printf''%p'、%s、%t@\n'| awk-vfs=、-vofs=、'{printf(%s、%s、.0f\n'、$1、$2、($3+116444473600)*10000000)}>${outputfile
进行这种转换的目的是什么?将unixtime转换为FILETIME可以让Windows应用程序读取时间:)我刚刚在标记中添加了awk,如果使用exec\+代码>而不是exec…\代码>。(也就是说,如果您的查找支持+
,那么它会更快,所以我应该说您的查找可能支持+
)代码>为每个名称生成单独的shell。使用+
将向一个shell传递许多路径,然后shell可以在这些路径上进行迭代。