Sua solução kludgy não é tão ruim para começar ... você está perdendo o fato de que não só pode awk dar-lhe o número de linhas, você também pode instruí-lo para exit com o código de status correto para que você possa encadeá-lo com o comando cp :
for file in * ; do awk 'NR==3{exit}END{exit NR!=2}' "$file" && cp "$file" /tmp; done
NR é o número de registros , e como sugerido na resposta do @don_crissti , podemos usar a NR==3 check para parar o processamento adicional uma vez encontramos uma terceira linha.
NR!=2 parece engraçado, porque os valores de awk do true/false são 1/0 , mas no shell, precisamos que 0 represente um status de sucesso para que && funcione corretamente. O inverso disso também funciona (dependendo de quão strongmente você reage a ver != ):
for file in * ; do awk 'NR==3{exit}END{exit NR==2}' "$file" || cp "$file" /tmp; done