使用cut,colrm,awk和sed的奇怪问题:无法从pipe道stream中剪切字符

我已经创build了一个脚本来枚举目录下的所有文件。 我想通过使用pv来添加一些进度反馈,因为我通常从根目录使用它。

问题是find它的时间输出总是包含小数秒(%TT),但我不想logging这么多的细节。

如果我写一个脚本来完成所有的事情,我会得到正确的结果。 但是如果我使用中间文件在“秒”中进行估计,结果会发生变化,我不明白为什么。

这个版本给出了正确的结果:

#!/bin/bash find -printf "%11s %TY-%Tm-%Td %TT %p\n" 2> /dev/null | # - Remove the fractional seconds from the time # before: 4096 2011-01-19 22:43:51.0000000000 . # after : 4096 2011-01-19 22:43:51 . colrm 32 42 | pv -ltrbN "Enumerating files..." | # - Sort every thing by filename sort -k 4 

但sorting可能需要很长时间,所以我尝试了类似的方法,以获得更多的反馈:

 #!/bin/bash TMPFILE1=$(mktemp) TMPFILE2=$(mktemp) # Erase temporary files before quitting trap "rm $TMPFILE1 $TMPFILE2" EXIT find -printf "%11s %TY-%Tm-%Td %TT %p\n" 2> /dev/null | pv -ltrbN "Enumerating files..." > $TMPFILE1 LINE_COUNT="$(wc -l $TMPFILE1)" #cat $TMPFILE1 | colrm 32 42 | #1 #cat $TMPFILE1 | cut -c1-31,43- | #2 #cut -c1-31,43- $TMPFILE1 | #3 #sed s/.0000000000// $TMPFILE1 | #4 awk -F".0000000000" '{print $1 $2}' $TMPFILE1 | #5 pv -lN "Removing fractional seconds..." -s $LINE_COUNT > $TMPFILE2 echo "Sorting list by filenames..." >&2 cat $TMPFILE2 | sort -k 4 

5个“解决scheme”都不起作用。 “.0000000000”部分留在输出中。

有人能解释为什么吗?

我的最终解决scheme是将切割操作与查找结合起来,并只使用一个临时文件。 只有sorting是分开完成的。

您可以使用字段精度说明符(至少使用GNU find 4.4.2)将参数中的秒数截断为-printf

 find -printf "%11s %TY-%Tm-%Td %.8TT %p\n" 

这留下了“HH:MM:SS”中的八个字符。

我的答案的其余部分可能是没有意义的:

#1-5的原因是wc的输出包括文件名(尤其是空格)。 该空间导致pvwc命令中查看文件名作为输入文件。 命令行参数的优先级高于stdin。 由于恰好与通过管道传递的输入文件相同,输出文件看起来像一个未处理的输入文件(因为它是,因为管道被忽略)。

只捕获没有文件名的计数:

 LINE_COUNT=$(wc -l < "$TMPFILE1") 

这里有一些小的改进:

 < $TMPFILE1 colrm 32 42 | #1 No need for cat 

要么

 colrm 32 42 < $TMPFILE1 | #1 < $TMPFILE1 cut -c1-31,43- | #2 

要么

 cut -c1-31,43- < $TMPFILE1 | #2 sed s/\.0000000000// $TMPFILE1 | #4 The dot should be escaped 

如果这是一个真正的工具,而不仅仅是一个玩具,那么我就把“进度反馈”全部放在一起……也许回想起来,当它不复杂你的生活。 与此同时,你可能花费更多的时间来想出如何提供反馈,而不是等待你的脚本返回。

如果你绝对必须给一些反馈,然后只是回声“排序wc -l $TMPFILE行…”

你会感觉到需要花费多少时间才能从经验中筛选出如此多的线路。

吻我的儿子,吻它。