1. bash / Говнокод #12698

    −116

    1. 1
    pattern=hidden; find . | grep -e ".*\.java$" | xargs sh -ac 'for arg in $@; do cat -n $arg | grep -e "$pattern" > /dev/null && echo $arg && cat -n $arg | grep -e "$pattern"; done'

    Нужно было поискать юзаджи по коду.
    Вот такое вот наворотил.
    Каюсь...

    Запостил: myzone, 06 Марта 2013

    Комментарии (19) RSS

    • Что здесь плохого, если это одноразовая команда? ;)

      Я обычно говнокодю подобный поиск как-то так:
      grep -r --include \*.java hidden *

      Я так понимаю этот код написан как раз ради того, чтобы убрать префиксы, и выводить имя файла только 1 раз?
      Ответить
      • Говно вот тут:
        cat -n $arg | grep -e "$pattern" > /dev/null && echo $arg && cat -n $arg | grep -e "$pattern";

        Грепаем 2 раза только для того, чтобы не выводить имен файлов без совпадений.

        PS Да, одноразовая, хотя может быть оформлю как скриптик и положу в папочку со всякими утилитами, может еще когда пригодится.
        Ответить
        • Здесь походу без какого-нибудь буфера не обойтись: хоть как придется сохранять stdout в переменную или файлик, а потом выводить имя и накопленные данные, если выхлоп grep'а был не пустым.
          Ответить
          • Именно, но я не знал как это сделать, поэтому получилось то, что получилось ;)
            Ответить
        • так а чем `grep -n` не устраивает?? вот будут тебе и номера строк...

          grep -n -r --include \*.java hidden *


          еще, если ты в VIM разбераешься, можешь в нем :grep или :vim коммандами пользоватся. :vim медлее чем :grep но там тебе и регулярки почти полноценные, и маски файлов человеческие.
          например, аналог в VIM:
          :vim /pattern/ **/*.java
          а потом :cn и :cp (у меня на F5 и F6 посаженые) (или :cw) что бы по результатам ходить.
          Ответить
          • > так а чем `grep -n` не устраивает??
            Видимо тем, что выводит имя файла в каждой строке. А myzone хочется, чтобы имя файла выводилось 1 раз перед самими совпадениями.
            Ответить
    • Ну по крайней мере первый пайп можно было легко реализовать в самом find, да и вообще, лучше вызывать grep через exec - проверено (изза мудака который решил положить в репозитори Grunt со всеми плагинами) - работает ощутимо быстрее.
      Да и писать чуть меньше даже получится.
      Ответить
      • А есть сколь-нибудь ощутимая разница в скорости выполнения find dir -exec grep pattern {} ';' и find dir | xargs grep pattern?
        Ответить
        • Т.как в последнее время больше в Сигвине, к сожалению, то разница более чем существенная - пайп может сломаться, раз на сто примерно.
          Ответить
          • Да, на моей Linux-машине тоже ощутимый профит есть, буду знать.
            $ time find /usr -type f | xargs grep import
            
            find /usr -type f  0.36s user 1.91s system 0% cpu 7:52.49 total
            xargs grep import  5.88s user 8.76s system 2% cpu 8:17.21 total
            
            $ time find /usr -type f -exec grep import {} ';'
            
            find /usr -type f -exec grep import {} ';'  4.90s user 25.74s system 4% cpu 11:22.26 total
            Ответить
    • find . -type f -name '*.java' -exec grep -nHi 'hidden' {} + | awk 'BEGIN { FS=":" };{ print $1 }' | uniq

      Не? Хотя, наверное, можно было и короче (awk как-то не айс тут).
      Ответить
      • Здесь контент не выводится, только имена. Так можно и одним грепом обойтись:
        grep -rl hidden --include \*.java *
        Ответить
        • find . -type f -name '*.java' -exec grep -li -m 1 'hidden' {} + | xargs -I % sh -c '{ echo % ; grep -oni 'hidden' % ; }'

          А, я понял, ну тогда вот такое вот родилось.
          Ответить
          • А здесь тоже на джва раза прогрепывается файл. Походу без какого-нибудь буфера никак не обойтись.
            Ответить
            • Да, да, я не тот вариант скопировал: -m 1 нужно было изначально добавлять (так только если первое совпадение найдено, греп дальше не будет искать), хотя это, конечно не сильно поможет, но все таки.
              Ответить
      • А как по мне - можно попробовать всё на awk'е реализовать целиком.
        Ответить
        • Можно, но не очень красиво:

          find -name "*.java" -exec awk -v pat=hidden 'FNR==1 {i=0} $0~pat {if (!i++) print FILENAME":";  printf "%6d  %s\n",NR,$0}' {} +
          Ответить

    Добавить комментарий