Моя задача состояла в том, чтобы вывести количество файлов в текущем каталоге без использования команд ls
и wc
.
Я набрал в сценарии следующие строки:
#!/bin/bash
find . -maxdepth 1 -type f \( ! -iname ".*" \) > list3
grep .* -c list3 > /dev/tty
Вывод:
..:0
.6.1c.sh.swp:1
list3:22
в то время как, по моему мнению, это должно быть только:22
Почему это не работает?
решение1
Почему grep
не работает правильно?
Это не сработает, потому что вам нужно знать, grep
что .*
это именно тот шаблон, который вы ищете.
grep '.*' -c list3
Если вы не используете одинарные кавычки, ваша оболочка расширится .*
до имен каждого файла в вашем каталоге. Это называетсяРасширение имени файла. Например a.txt b.txt
, так grep
увидим:
grep a.txt b.txt -c list3
Содинарные кавычкипредотвратить расширение, вот путь, по которому следует идти.
Где ваша grep
команда неверна:
Кстати, вы тут с шаблоном не в том направлении идете. Точка .
в регулярном выражении совпадаетлюбойсимвол, а не буквальная точка. Смотритестраницаman
для получения дополнительной информации. Итак, ваше регулярное выражение в настоящее время говорит: "найти любой символ, а затем последовательность любых символов". Довольно избыточно.
Если вы действительно имеете в виду соответствие:
[точка] [что-нибудь еще]
… вам нужно экранировать точку:
\.*
find
Где можно улучшить вашу команду:
Я не знаю, что вы имеете в виду, говоря «избавиться»
\( ! -iname ".*" \)
Ваша find
команда добавит к любому файлу точку для текущего рабочего каталога, поэтому вы ничего здесь не удалите. Вы могли бы просто запустить:
find . -maxdepth 1 -type f
решение2
Для решения исходной проблемы подсчитаем файлы без ls
и wc
:
Чистый синтаксис оболочки:
files=0
for i in *; do
[ -f "${i}" ] && files=$((files+1))
done
echo ${files}
Чтобы добавить скрытые файлы в счетчик, просто измените настройки подстановки перед циклом for
.
Альтернатива: развлечение с find
расширением оболочки:
echo $(($(find -maxdepth 1 -type f -printf '+1')))