whereis python | sed 's/ /\n/g' | sort | uniq
Тогда у сортировки много вариантов
Если вы хотите изменить порядок:
whereis python | sed 's/ /\n/g' | sort -r | uniq
-r, --reverse
reverse the result of comparisons
если бы вы (могли )иметь несколько странных двоичных/исходных/ручных файлов, содержащих специальные символы:
-i, --ignore-nonprinting
consider only printable characters
Попробуйте это,
Count=0
for i in {$start..$stop}; do
Counter="$(ls /home/me/*/file_$i.txt 2> /dev/null | wc -l)"
Count=$((Count+Counter))
done
echo "$Count"
Если я вас правильно понял, цикл не нужен:
Допустим, диапазон от 12 до 76:
ls -l | grep -e "file_1[2-9].txt" -e "file_[2-6][0-9].txt" -e "file_7[0-6].txt"
Файлы с 12 по 19
"file_1[2-9].txt"
Файлы с 20 по 69:
"file_[2-6][0-9].txt"
Файлы с 70 по 76
"file_7[0-6].txt"
Не используйте цикл вообще. Вместо этого перечислите все файлы и используйте команду, например grep
или akw
, чтобы отфильтровать файлы между start
и stop
. printf
не будет иметь проблем Argument list too long
, так как это bash
встроенный -.
printf '%s\0' /home/me/*/file_*.txt |
grep -cEzf <(seq "$start" "$stop" | sed 's/.*/_&\.txt$/')
Здесь мы предполагаем, что у вас есть версии GNU grep
, которые могут обрабатывать нулевые байты. Это важно для безопасной обработки путей. Нулевой байт — единственный символ, который не может быть частью пути, поэтому мы можем использовать его для разделения путей.
Если у вас нет версии GNU, вы можете создать что-то, что разделяет пути символами новой строки, предполагая, что ни один из путей не содержит символ новой строки. Замените \0
на \n
и снимите флаг -z
.
Если вы измените …_*.txt
на что-то другое, возможно, вам также придется обновить команду sed
.
A bash
решение:
(
shopt -s nullglob
start=1 # change as needed
stop=500 # change as needed
printf '%s\n' $(printf '/home/me/*/file_%s.txt\n' $(seq "$start" "$stop")) | wc -l
)
Включите nullglob
, чтобы сопоставлять только существующие файлы и выполнять скрипт в подоболочке (…)
, поэтому нам не нужно определять предыдущее состояние nullglob
и сбрасывать его старое состояние по завершении. Внутренний printf
используется для генерации всех возможных шаблонов имен файлов, а внешний printf
необходим для интерпретировать *
как символ глобуса. Напечатанные выходные строки подсчитываются с помощью wc -l
.
Вы можете использовать подстановку процесса и grep -f для поиска только файлов в пределах диапазона.
. Для подсчета всех файлов с именем file _[0 -9]+.txt в диапазоне от 10 до 20:
start=10
end=20
ls -f1 | grep -F -f <(printf "file_%s.txt\n" $(seq ${start} ${end}))|wc -l
Не используйте eval
, если у вас нет другой альтернативы. Это потенциально опасно, в зависимости от содержимого переменных $start
и $stop
. Не стоит привыкать использовать его там, где он не нужен.
Не используйте вывод ls
ни для чего, кроме просмотра в терминале. Попытка разобрать ls
, даже самым простым способом, может привести к неудаче во многих отношениях. Используйте любое , которое может создать список имен файлов, разделенных NUL -, вместо:find -print0
часто является хорошим выбором.
bash, встроенный -в расширение последовательности {x..y}
, не может оценивать переменные, но отдельная программа seq
может принимать переменные в качестве аргументов. Он также имеет полезную опцию -s
для указания разделителя.
Для следующего требуется версия grep
, которая поддерживает параметр -z
для разделенных входных записей NUL -(, например. GNU, FreeBSD и большинство других современных версий grep
).
# build a regular expression matching the desired sequence
re="$(seq -s '|' "$start" "$stop")"
# use the RE with `find... -print0` and `grep -E -z -c`
find /home/me/*/ -maxdepth 1 -type f -name 'file_*.txt' -print0 |
grep -Ezc "/file_($re)\.txt$"
Например, если start=3
и stop=7
, то $re
будет 3|4|5|6|7
. Затем команда grep
расширится до :
grep -Ezc "/file_(3|4|5|6|7)\.txt$"
Кстати, аргументы -name 'file_*.txt'
для команды find
не требуются.Их можно отбросить, и конвейер все равно будет работать без ошибок. Все, что они делают, это сокращают входные данные, которые необходимо обработать с помощью grep
. В лучшем случае очень незначительная оптимизация.
напр.
find /home/me/*/ -maxdepth 1 -type f -print0 | grep -Ezc "/file_($re)\.txt$"
Сzsh
:
count=0 range="<$start-$stop>"
/home/me/*/file_$~range.txt(Ne['((!++count))'])
Дает подсчет без сохранения списка файлов в памяти.
<1-100>
- это оператор zsh glob, который соответствует десятичным числам в этом диапазоне (обратите внимание, что он соответствует 2, но также и 000002, например)$~var
аналогичен $var
, за исключением того, что содержимое $var
рассматривается как шаблон, а не буквальное значение. (Ne['code'])
является квалификатором глобуса N
:включает nullglob
для этого шаблона, чтобы он не терпел неудачу, если глобус не соответствует ни одному файлу (, что всегда имеет место здесь ). e['code']
выбирает файлы на основе оценки code
. Здесь код(((!++count))
)увеличивает $count
и всегда возвращает false, поэтому файлы не выбираются (, а $count
увеличиваются, и это все, что нас здесь интересует ).