Еще один способ bash, разработанный с помощью @Helio в чате:
for file in *
do
echo "$file"
[[ -f "$file" ]] || continue
[[ $file =~ (.*)(\.[^.]+)$ ]]
cp "$file" "output/${BASH_REMATCH[1]:-$file}_$(wc -l < "$file")${BASH_REMATCH[2]}"
done
Странный выглядящий монокристаллический парень с чахлой второй головой ((.*)(\.[^.]+)$) должен соответствовать только правильным расширениям (.foo, а не [F5]). Если расширения нет, тогда массив BASH_REMATCH будет пустым. Мы можем воспользоваться этим, используя значение по умолчанию для имени файла ${BASH_REMATCH[1]:-$file} и просто используя расширение как есть.
Чтобы обрабатывать файлы точек, вы могли бы использовать find, как предложено [d1 ] @Helio в чате .
find -maxdepth 1 -type f -printf '%P\0' |
while IFS= read -r -d '' file
do
[[ $file =~ (.*)(\.[^.]+)$ ]]
cp "$file" "output/${BASH_REMATCH[1]:-$file}_$(wc -l < "$file")${BASH_REMATCH[2]}"
done