- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在文件夹中,我想打印包含 n=27
行或更少行的每个 .txt
文件的名称。我可以做
wc -l *.txt | awk '{if ($1 <= 27){print}}'
问题是文件夹中的许多文件有数百万行(而且行很长),因此命令 wc -l *.txt
非常慢。原则上,一个进程可以计算行数,直到找到至少 n
行,然后继续处理下一个文件。
什么是更快的替代方案?
仅供引用,我在 MAC OSX 10.11.6
这是对 awk
的尝试
#!/bin/awk -f
function printPreviousFileIfNeeded(previousNbLines, previousFILENAME)
{
if (previousNbLines <= n)
{
print previousNbLines": "previousFILENAME
}
}
BEGIN{
previousNbLines=n+1
previousFILENAME=NA
}
{
if (FNR==1)
{
printPreviousFileIfNeeded(previousNbLines, previousFILENAME)
previousFILENAME=FILENAME
}
previousNbLines=FNR
if (FNR > n)
{
nextfile
}
}
END{
printPreviousFileIfNeeded(previousNbLines, previousFILENAME)
}
可以称为
awk -v n=27 -f myAwk.awk *.txt
但是,代码无法打印出完全空的文件。我不确定如何解决这个问题,也不确定我的 awk 脚本是否适合。
最佳答案
使用 GNU awk 获取 nextfile 和 ENDFILE:
awk -v n=27 'FNR>n{f=1; nextfile} ENDFILE{if (!f) print FILENAME; f=0}' *.txt
使用任何 awk:
awk -v n=27 '
{ fnrs[FILENAME] = FNR }
END {
for (i=1; i<ARGC; i++) {
filename = ARGV[i]
if ( fnrs[filename] < n ) {
print filename
}
}
}
' *.txt
无论输入文件是否为空,它们都可以工作。非 gawk 版本的注意事项与您当前的其他 awk 答案相同:
awk 'script' foo bar foo
)并且您希望它显示多次,并且awk 'script' foo FS=, bar
)gawk 版本没有这样的限制。
更新:
测试上述 GNU awk 脚本和 the GNU grep+sed script posted by xhienne 之间的时序因为她说她的解决方案比纯 awk 脚本快
我创建了 10,000 个输入文件,所有的长度都在 0 到 1000 行之间,使用这个脚本:
$ awk -v numFiles=10000 -v maxLines=1000 'BEGIN{for (i=1;i<=numFiles;i++) {numLines=int(rand()*(maxLines+1)); out="out_"i".txt"; printf "" > out; for (j=1;j<=numLines; j++) print ("foo" j) > out} }'
然后对它们运行 2 个命令并获得这些第 3 次运行计时结果:
$ time grep -c -m28 -H ^ *.txt | sed '/:28$/ d; s/:[^:]*$//' > out.grepsed
real 0m1.326s
user 0m0.249s
sys 0m0.654s
$ time awk -v n=27 'FNR>n{f=1; nextfile} ENDFILE{if (!f) print FILENAME; f=0}' *.txt > out.awk
real 0m1.092s
user 0m0.343s
sys 0m0.748s
两个脚本都产生相同的输出文件。以上是在 cygwin 上以 bash 运行的。我预计在不同的系统上,计时结果可能会略有不同,但差异总是可以忽略不计。
要打印 10 行,每行最多 20 个随机字符(请参阅注释):
$ maxChars=20
LC_ALL=C tr -dc '[:print:]' </dev/urandom |
fold -w "$maxChars" |
awk -v maxChars="$maxChars" -v numLines=10 '
{ print substr($0,1,rand()*(maxChars+1)) }
NR==numLines { exit }
'
0J)-8MzO2V\XA/o'qJH
@r5|g<WOP780
^O@bM\
vP{l^pgKUFH9
-6r&]/-6dl}pp W
&.UnTYLoi['2CEtB
Y~wrM3>4{
^F1mc9
?~NHh}a-EEV=O1!y
of
要在 awk 中完成所有操作(这会慢很多):
$ cat tst.awk
BEGIN {
for (i=32; i<127; i++) {
chars[++charsSize] = sprintf("%c",i)
}
minChars = 1
maxChars = 20
srand()
for (lineNr=1; lineNr<=10; lineNr++) {
numChars = int(minChars + rand() * (maxChars - minChars + 1))
str = ""
for (charNr=1; charNr<=numChars; charNr++) {
charsIdx = int(1 + rand() * charsSize)
str = str chars[charsIdx]
}
print str
}
}
$ awk -f tst.awk
Heer H{QQ?qHDv|
Psuq
Ey`-:O2v7[]|N^EJ0
j#@/y>CJ3:=3*b-joG:
?
^|O.[tYlmDo
TjLw
`2Rs=
!('IC
hui
关于bash - 列出包含 `n` 或更少行的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52632590/
在我的 Rails 应用程序中,我有几个处理 Assets (附件、图片、 Logo 等)的模型。我正在使用 attachment_fu,到目前为止,我有 3 个不同的表用于将信息存储在我的 MySQ
我是一名优秀的程序员,十分优秀!