Имеют документы, хранящиеся в файловой системе, которая включает в себя «ежедневные» каталоги, например. 20050610. В сценарии bash я хочу перечислить файлы в течение нескольких месяцев этих каталогов. Поэтому я запускаю команду поиска find <path>/200506* -type f >> jun2005.lst
. Хотелось бы проверить, что этот набор каталогов не является набором нулей перед выполнением команды find. Однако, если я использую if[ -d 200506* ]
я получаю «слишком много заданы параметры ошибки. Как я могу обойти это?bash тестирование группы каталогов для существования
ответ
Ошибка «слишком много аргументов» возникает из-за того, что существует огромное количество файлов и превышает ограничение аргумента командной строки. Это происходит из-за наличия более чем одной или двух каталогов, которые соответствуют glob. Ваш glob «200506 *» расширяется примерно до «20050601 20050602 20050603 ...», а тест -d
ожидает только одного аргумента.
$ mkdir test
$ cd test
$ mkdir a1
$ [ -d a* ] # no error
$ mkdir a2
$ [ -d a* ]
-bash: [: a1: binary operator expected
$ mkdir a3
$ [ -d a* ]
-bash: [: too many arguments
Ответ на zed_0xff находится на правильном пути, но я хотел бы использовать другой подход:
shopt -s nullglob
path='/path/to/dirs'
glob='200506*/'
outfile='jun2005.lst'
dirs=("$path"/$glob) # dirs is an array available to be iterated over if needed
if ((${#dirs[@]} > 0))
then
echo "directories found"
# append may not be necessary here
find "$path"/$glob -type f >> "$outfile"
fi
Положение котировок в "$path"/$glob
против "$path/$glob"
имеет важное значение для этой работы.
Edit:
исправление сделано, чтобы исключить файлы, которые соответствуют Glob (поэтому только каталоги включены) и обрабатывать очень необычный случай каталога с именем буквально как Глоба («200506 *»).
S=200506*
if [ ${#S} -gt 6 ]; then
echo haz filez!
else
echo no filez
fi
не очень элегантный один, но без каких-либо внешних инструментов/команд (если не думать из «[», как и внешней)
подсказка, если есть некоторые файлы, совпадающие, то «S» переменный будет содержать имена разделителей с пространством. в противном случае он будет содержать «200506 *» строку самих.
Вы можете нас найти ls
следующим образом:
if [ -n "$(ls -d | grep 200506)" ]; then
# There are directories with this pattern
fi
Поскольку в большинстве оболочек есть ограничение на длину командной строки: что-нибудь вроде «$ (ls -d | grep 200506) «или/path/200506 * будет угрожать переполнением лимита. Я не уверен, что подстановки и расширения glob относятся к нему в BASH, но я так полагаю. Вам нужно было бы протестировать его и проверить bash документы и источник, чтобы быть уверенным
ответ в упрощая вопрос
find <path>/200506* -type f -exec somescript '{}' \;
Где somescript это скрипт, который делает тест-то вроде этого, может быть:...
#!/bin/sh
[ -d "[email protected]" ] && echo "[email protected]" >> june2005.lst
Passing june2005.lst к скрипту (совет: используйте переменную окружения) и имея дело с любой возможностью, что 200506 * может расширяться до tooo огромного пути к файлу, оставаясь в качестве упражнения для OP;)
Интеграция всего объекта в линию трубопровода или адаптация более общего языка сценариев даст повышение производительности, путем минимизации количества порожденных оболочек. Теперь это будет весело. Вот вам подсказка, используйте -exec и другую программу (awk, perl и т. Д.), Чтобы выполнить тест каталога как часть фильтра с одной строкой и сохранить >> june2005.lst в команде find.
prefix="/tmp/path"
glob="200611*"
n_dirs=$(find $prefix -maxdepth 1 -type d -wholename "$prefix/$glob" |wc -l)
if [[ $n_dirs -gt 0 ]];then
find $prefix -maxdepth 2 -type f -wholename "$prefix/$glob"
fi
- 1. Applescript-тестирование для существования файла
- 2. Тестирование существования метода
- 3. Тестирование печенья существования в Django
- 4. Тестирование UIApplicationOpenSettingsURLString существования с Swift
- 5. Bash существования файла проверка отсутствует]
- 6. Тестирование существования повторяющихся полей в сообщении protobuff
- 7. Удаление каталогов в bash
- 8. Bash: поиск дерева каталогов
- 9. PHP: тестирование существования ячейки в многомерном массиве
- 10. Тестирование существования функции (функция с динамической привязкой)
- 11. ios/object-c: Тестирование существования NSUserDefault
- 12. Тестирование существования подключенного компонента с реакцией-редукцией
- 13. Bash, переплетение каталогов
- 14. Bash скрипт для анализа каталогов и каталогов печать резюме
- 15. Права на группы, необходимые для нескольких каталогов
- 16. Java тестирование для папки на Ubuntu существования 14.04
- 17. Применить переменные bash для каталогов (рекурсивный)
- 18. Bash скрипт для каталогов обработки (Regex)
- 19. логический ИЛИ критерий существования для переменных оболочки в bash
- 20. Bash Script для проверки существования имени пользователя в/etc/passwd
- 21. Параллельное тестирование с bash
- 22. BASH: размер Сумма одноименных каталогов
- 23. Тестирование, если для каждой группы возвращается более 1 группы XSL
- 24. Резервное копирование каталогов с Bash
- 25. Bash Script Рекурсивное дерево каталогов
- 26. Неожиданный список каталогов bash с *
- 27. BASH - предельная глубина контура каталогов
- 28. Unix: Bash: Поиск определенных каталогов
- 29. Рекурсивная функция bash (итератор каталогов)
- 30. Технологические группы пар файлов из нескольких каталогов
Отмечено, что -d ожидает один аргумент. Поскольку проверяемые каталоги «ежедневно» могут быть до 31 в месяц. Я несколько разных «видов» документов и запускаю команды поиска последовательно. найти/а/200506 * >> выходной_файл найти /б/200506 * >> выходной_файл найти /с/200506 * >> выходной_файл Это означает, что если один в середине терпит неудачу, я предполагаю, что после них не выполняются, и весь скрипт терпит неудачу. Это верно? Решение Dennis будет работать в контексте моего сценария. FYI, никакие файлы не соответствуют глобусу по имени, и ни один каталог точно не соответствует glob. –
@ Джейм Джонс: Я не уверен, что я последую за тобой. Что вы можете сделать, это что-то вроде: 'globs = ('200506 * /' '200507 * /' '200508 *'); outfiles = ("jun2005" "jul2005" "aug2005"); subdirs = (a b c); для glob в $ {globs [@]}; do outfilebase = $ {outfiles [i ++]}; для subdir в $ {subdirs [@]}; do path = "/ top/of/path/$ dir"; выходной_файл = "$ outfilebase $ subdir.lst"; dirs = ... [как указано выше] ... if ... find ... else echo «Каталогов не найдено для $ glob под $ subdir"; fi' [untested] –