- 1
- 2
- 3
- 4
{
(cd "$DIR"; ls -1);
{ xml2 < $XML | grep '/list/files/@path=' | cut -d = -f 2 | cut -d / -f 2 | sort | uniq; }
} | sort | uniq --count | grep '^ *1' | awk '{print $2}' | (cd "$DIR"; xargs --no-run-if-empty rm -v)
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
−125
{
(cd "$DIR"; ls -1);
{ xml2 < $XML | grep '/list/files/@path=' | cut -d = -f 2 | cut -d / -f 2 | sort | uniq; }
} | sort | uniq --count | grep '^ *1' | awk '{print $2}' | (cd "$DIR"; xargs --no-run-if-empty rm -v)
Удаляет из "$DIR" всё, что не описано в files.xml.
greno 10.11.2011 23:30 # +3
xmllint --xpath не берет?
> uniq --count | grep '^ *1' | awk '{print $2}'
uniq -u же
> xargs --no-run-if-empty rm -v
лучше ./'{}' (а то мало ли, что в $XML
зы... 2 cd - тоже не очень, и есть `combine' из `moreutils' (правда, хотя бы один из входов должен быть файлом), sort | uniq -> sort -u (и в данном случае можно без него)
Dummy00001 11.11.2011 00:35 # 0
я подобные задачи - пересечение (предварительно отсортированых) множеств - приучился diff делать, который спокойно башевы `<(cmd)` конструкцие пережевывает и более портабельный. по выводу дифа можно грепнуть что есть только в левой части (^<), или что есть только в правой части (^>).
и вместо `xargs` который по жизни кучу граблей портабельности имеет (например в hp-ux), я просто на лету sed'ом генерю комманды и потом их пайпю в шелл. типа: "ls -1 | sed 's!^!rm -rf !' | sh" - в особенности со встроеными коммандами это работает на ура.
greno 11.11.2011 08:34 # +1
Всё-таки s/и/или/. В 1 случае и `combine' поймёт `process substitution'.
Во 2 сойдет `comm', разве что -123 не интуитивны, и для надёжного OR или XOR (только в одном) хуже подходит.
> "ls -1 | sed 's!^!rm -rf !' | sh"
"| sh" да на левом входе... "touch tilda". Лучше system(), посиксовый awk вроде поддерживает, или обернуть:
+Профит в виде чтения переменных, для awk же лучше явно передавать.
> работает на ура
Почему-то :P вспомнилось: http://bestbash.org/b_25471
gegMOPO4 11.11.2011 11:41 # +1
greno 11.11.2011 14:43 # 0
Dummy00001 11.11.2011 14:13 # 0
потому что баш стоит почти везде - в отличии от GNU *-tools/*utils
админы тоже любят баш - а GNU часто не совместим с системными скриптами почему их избегают ставить.
> "| sh" да на левом входе... "touch tilda". Лучше system(), посиксовый awk вроде поддерживает, или обернуть:
трюк с '| sh' позволяет (если сперва убрать '| sh') преварительно увидеть какие комманды будут исполнятся и их отдельно протестировать.
другим образом протестировать комманды использующие </> редиректы почти невозможно.
> +Профит в виде чтения переменных, для awk же лучше явно передавать.
да, да. но. как по мне почти все что `while read` может делать, можно сделать и без него. я стараюсь почти для всего найти вариант с пайпами что бы туда еще можно было и xargs всобачить. например удаление файлов по одиночке будет подтормаживать на больших количествах - с xargs'ом для групировки файлов заметно быстрее. и xargs совместим с '| sh' трюком :)
например, сравни это:
с вот этим:
пайплайнинг и паралелизация в полный рост. ;)
greno 11.11.2011 14:45 # 0
greno 11.11.2011 14:45 # 0
greno 11.11.2011 15:06 # 0
Вы сидели на стуле "портабельность", что несколько ослабляет аргумент.
> например удаление файлов по одиночке
Именно в этом случае `find .. -delete'.
> xargs совместим с '| sh'
Не всегда хаrgs критичен (есть и find +), имхо, это того не стоит.
Dummy00001 11.11.2011 15:25 # 0
> Вы сидели на стуле "портабельность", что несколько ослабляет аргумент.
`xargs -n NNN` - это тоже POSIX.
использование подстановки типа '-I {}' - которое тоже к слову POSIX - по моему опыту минное поле. потому что куча find'ов не правильно обрабатывает `-I` параметр если нужно вместо '{}' какую другую строку использовать.
> этц про find, включая +
насчет `+` мой первый же тест (минуту назад (-: ) показал проблему:
"find: echo: Argument list too long". другими словами это неправильная замена xargs, т.к. xargs он в обе стороны работает: с одной стороны он агрегирует много строк в меньшее количество строк, с другой стороны он регулирует длину комманды что бы она за лимит не выходила.
greno 11.11.2011 15:49 # 0
find и -I не очень понял, можно пример? Об этом ограничении: plus sign that follows an argument containing the two characters "{}" (всмысле аргумент должен быть последним).
> find: echo: Argument list too long
Не воспроизводится. Судя по ману и проверке тоже вызавает несколько раз. Но буду иметь ввиду.
Dummy00001 11.11.2011 16:56 # 0
оопс. это я стормозил и попутал с совсем не той проблемой. `-I` это у xargs, а не find. и эта проблема тут ни причем.
ЗЫ xargs на некоторых платформах если указать `-I` параметр перестают подставлять имена файлов вообще и просто комманду буквально как написано выполняют.
> > find: echo: Argument list too long
> Не воспроизводится
это у тебя в каталоге мало файлов. напусти чего-нибудь такое:
и попробуй еще раз, например с "find $PWD" а не просто "find ."
фишка `find -exec +` что он запускает команду один раз на весь подкаталог. если в каталоге слишком много файлов, то длина команды легко переваливает за лимит (в общем случае 32К) и команда не выполняется.
gegMOPO4 11.11.2011 18:16 # 0
Из последней команды видно, что echo выполнилось 4 раза.
Dummy00001 11.11.2011 19:16 # 0
не уверен. глянь в свой /usr/include/limits.h и посмотри чему равно ARG_MAX. (на линухе - сразу в /usr/include/linux/limits.h)
> $ echo * | wc
хехе. старая шутка. попробуй /bin/echo. echo вызываемое на прямую из шелла есть встроеная комманда - и поэтому обходит системные ограничения.
> $ find -exec echo '{}' + | wc
если запустить на моем линухе `find -exec echo '{}' + >/dev/null` первые три строки выглядят так:
find: echo: Argument list too long
find: echo: Argument list too long
find: echo: Argument list too long
и wc показывает неправильные цифры.
да, разбивает, но только сильно не помогает - наверное потому что народ забывает что ARG_MAXом ограничивается сумма длины коммандной строки и размера переменных окружения.
самый прикол что на моем SLES 10.2 ARG_MAX самый маленький - 128K. на 10й солярке 2MБ. на AIX официально 24К, но я не вижу что бы этот лимит какой-то роли играл. HP-UX - 1MB.
у тебя на системе ARG_MAX стоит в минимум 512К
вообщем разброд и шатание, ну да я уже привык это ограничение обходить.
greno 11.11.2011 19:57 # 0
У меня было так (лимит вроде 128k):
/bin/echo /media/*/*/*/*/*/*
bash: /bin/echo: Argument list too long
find /media -maxdepth 6 -mindepth 6 -exec echo '{}' +
выводит
gegMOPO4 11.11.2011 19:57 # 0
А find у вас какой-то кривой.
gegMOPO4 11.11.2011 20:31 # 0
Dummy00001 11.11.2011 20:44 # 0
размер стека (главного потока) как правило большой (и у меня 8МБ) что бы его так легко переполнить.
ARG_MAX как лимит существует потому что эти данные - коммандная строка и окружения - копируются в exec() через кернел в образ нового процесса. а кернела они любят что бы на все буфера было какое-то вразумительное ограничение, т.к. кернелова память не свапится.
да и если процесс стек переполнит, то он будет просто убит каким SEGV. красивых сообщениях об ошибках ты не увидишь.
gegMOPO4 11.11.2011 22:12 # 0
Dummy00001 11.11.2011 19:21 # 0
я смотрю трюков для обхода ограничения намного больше чем я предполагал. и кое что из того что я думал не рабоатет - на самом деле работает.
gegMOPO4 11.11.2011 20:29 # +1
nil 14.07.2012 23:22 # 0
gegMOPO4 11.11.2011 11:33 # 0
x28cnp 11.11.2011 13:40 # 0
eth0 12.11.2011 11:13 # 0
Lure Of Chaos 13.11.2011 16:24 # 0
eth0 13.11.2011 18:51 # 0
Бывший босс делал какую-то свою хитрую систему, ему там было нужно сделать nslookup множества доменов, получение уникальных строк и засовывание айпишников в файервол. Я небольшой кусочек помог, но там вышел какой-то дикий скрипт на баше. Ради интереса посидел два часа, переписал полностью на gawk. Офигенная штука, скажу я. И с текстами работать умеет. И как-то там парсить. Самое то.
lucidfoxGovno 13.11.2011 20:02 # −4
GAWK в помойку
Lure Of Chaos 13.11.2011 20:27 # +1
lucidfoxGovno 13.11.2011 20:31 # −4
eth0 15.11.2011 13:07 # 0
lucidfoxGovno 13.11.2011 16:36 # −6
guest8 09.04.2019 11:58 # −999