Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在bash中更改find-printf的值_Bash_Awk_Find_Printf - Fatal编程技术网

在bash中更改find-printf的值

在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为每个文件和目录打印一行:

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可以在这些路径上进行迭代。