Цветной вывод grep: Не GREP_OPTIONS, а не псевдоним

http: // localhost: 8080 / blog / 1-and-here-the -slug

bar, foo и 1-and-here-the-slug - это файлы. Я хочу, чтобы они были каталогами с одним файлом в них с именем index.html и при этом не нарушали пути к ресурсам (CSS, JS и т. Д.).

├── blog
│   └── 1-and-here-the-slug
│       └── index.html

Когда вы открываете http: // localhost: 8080 / blog / 1-and-here-the-slug , текущий каталог - blog , если вы переименуете эту страницу в blog / 1-and-here-the-slug / index.html , ваш новый текущий каталог будет blog / 1-and-here-the-slug . Таким образом, вы нарушите относительные пути внутри ресурса (CSS, JS), если таковые имеются. И нет способа решить этот вопрос без изменения внутреннего HTML файлов .

Лучшее, что вы можете сделать, - это переименовать файлы без какого-либо расширения в расширение html.

├── blog
│   └── 1-and-here-the-slug.html
  1. Сохраняя тот же каталог, вы можете рекурсивно использовать команду rename :

Пример:

  find tmp -type f ! -name '*.*' | rename -nv 's/(.*)/$1.html/'
  1. Вы можете создавать новые каталоги, но это нарушит относительные ресурсы, если таковые имеются

Ex :

  find tmp -type f ! -name '*.*' | while read file; do
       mv $file $file.tmp;
       mkdir $file;
       mv $file.tmp $file/index.html;
 done

Вы можете играть, вставив в файл тег , чтобы указать правильный путь к ресурсам, но это будет тяжелой и дорогой работой

  1. * * Или лучше используйте параметр -E wget

EDIT: чтение страницы руководства wget дает вам два замечательных варианта

  -E 
 --adjust- extension 
Если загружен файл типа application / xhtml + xml или text / html 
и URL не заканчивается регулярным выражением \. [Hh] [Tt] [Mm] [Ll] ?, эта опция 
приведет к добавлению суффикса .html к локальному имени файла. 
 
 -k 
 --convert-links 
После завершения загрузки преобразуйте ссылки в документе, чтобы 
сделать их подходящими для локальных просмотр. Это влияет не только на видимые 
гиперссылки, но и на любую часть документа, которая ссылается на внешнее содержимое, 
например на встроенные изображения, ссылки на таблицы стилей, гиперссылки на не - 
HTML содержание и т. д. 
 
10
24.03.2017, 12:24
5 ответов

Причина, по которой переменная GREP_OPTIONS устарела, заключается в том, что она имеет тенденцию вызывать проблемы, когда где-то в сценарии вызывается grep , и сценарий не работает с альтернативными параметрами, которые появляются из переменной. Если вы напишете сценарий оболочки для grep , то у вас будет та же проблема, , если вы не дадите ему другое имя .

$ cat ~/bin/cgrep
#!/bin/sh
exec grep --color=always "$@"
$ find … -exec cgrep … {} +

Или сохраните ваши любимые опции в переменной. В оболочках, отличных от zsh, это громоздко, если параметры содержат символы подстановки ( \ [*? ), но в противном случае вы можете просто использовать переменную без кавычек, чтобы получить команду с аргументами.

cgrep=(grep --color=always)
find … -exec $cgrep … {} +

Обратите внимание, что GNU и BSD grep могут рекурсивно обрабатывать дерево каталогов, что в большинстве случаев устраняет необходимость в find в сочетании с grep .

3
27.01.2020, 20:00

В документации, которую вы предоставляете с первой стратегией, говорится:

Пожалуйста, используйте псевдоним или сценарий вместо этого. Например, если grep находится в каталоге '/ usr / bin', вы можете добавить $ HOME / bin к вашему PATH и создать исполняемый скрипт $ HOME / bin / grep, содержащий следующее:

#! /bin/sh
export PATH=/usr/bin
exec grep --color=auto --devices=skip "$@"

Итак, если псевдоним невозможно для вы, сценарий оболочки - единственный способ.

3
27.01.2020, 20:00

Самый простой способ - использовать псевдоним (стратегия 3). Если вам действительно нужна команда xargs , вы все равно можете переопределить ее с помощью функции bash.

alias grep='grep --color'
xargs() {
    local args
    for ((i=1; i<=$#; i++))
    do
            if [[ "-E -L -P -I -s -d" == *"${!i}"* ]]; then
                    ((i=i+1))
            elif [[ ${!i:0:1} != "-" ]]; then
                    if [[ ${!i} == "grep" ]]; then
                            args="--color"
                    fi
                    /usr/bin/xargs ${@:1:i} $args ${@:i+1}
                    return;
            fi
    done
}

Но это не лучше, чем использование команды-оболочки, которая, по-видимому, является рекомендуемым решением команды grep :

/usr/local/bin/grep:

#!/bin/bash
/bin/grep --color "$@"

По моему скромному мнению, вам следует обратиться к grep команда разработчиков попросила их предоставить простую замену переменной GREP_OPTIONS , которая включит цвет в grep в соответствии с некоторой переменной среды.

Для них было бы довольно просто включить по умолчанию параметр цвет или когда был установлен GREP_COLORS .

0
27.01.2020, 20:00

Некоторые из причин, по которым ОП заявил, что варианты не подходят, не имеют под собой никакой основы. Здесь я показываю, какие эффекты дает использование стратегии OP 4:


В большинстве дистрибутивов, grep установлен в /bin (типичный) или /usr/bin (OpenSUSE, возможно и другие), а стандартный PATH содержит /usr/local/bin перед /bin или /usr/bin. Это означает, что если вы создадите /usr/local/bin/grep с

#!/bin/sh
exec /bin/grep --color=auto "$@"

где /bin/sh - это POSIX-совместимая оболочка, предоставляемая вашим дистрибутивом, обычно bash или dash. Если grep находится в /usr/bin, то сделайте так

#!/bin/sh
exec /usr/bin/grep --color=auto "$@"

Накладные расходы этого сценария минимальны. Оператор exec означает, что интерпретатор скрипта заменяется двоичным файлом grep; это означает, что оболочка не остается в памяти, пока выполняется grep. Таким образом, единственным накладным расходом является одно дополнительное выполнение интерпретатора сценария, т.е. небольшая задержка в настенных часах. Задержка примерно постоянна (меняется только в зависимости от того, находятся ли grep и sh уже в кэше страниц или нет, и от того, насколько доступна полоса пропускания ввода-вывода), и не зависит от того, как долго выполняется grep или сколько данных он обрабатывает.

Итак, сколько времени занимает эта задержка, т.е. накладные расходы, добавляемые скриптом-оберткой?

Чтобы узнать это, создайте вышеприведенный скрипт и запустите

time /bin/grep --version
time /usr/local/bin/grep --version

На моей машине первый занимает 0,005 с реального времени (при большом количестве запусков), тогда как второй занимает 0,006 с реального времени. Таким образом, накладные расходы при использовании обертки на моей машине составляют 0,001 с (или меньше) на вызов.

Это незначительно.

Я также не вижу в этом ничего "грязного", потому что многие распространенные приложения и утилиты используют тот же подход. Чтобы увидеть список таковых на вашей машине в /bin и /usr/bin, просто выполните

file /bin/* /usr/bin/* | sed -ne 's/:.*shell script.*$//p'

На моей машине вышеприведенный вывод включает egrep, fgrep, zgrep, which, 7z, chromium-browser, ldd и xfig, которые я использую довольно часто. Если вы не считаете весь дистрибутив "грязным" за то, что он полагается на скрипты-обёртки, у вас нет причин считать такие скрипты-обёртки "грязными".


Что касается проблем, которые может вызвать такой скрипт-обёртка:

Если только человеческие пользователи (в отличие от скриптов) используют версию grep, которая по умолчанию поддерживает цвет, если вывод осуществляется на терминал, то скрипт-обёртка может быть назван colorgrep или cgrep или как угодно, по мнению ОП.

Это позволяет избежать всех возможных проблем совместимости, поскольку поведение grep никак не меняется.


Включение опций grep с помощью скрипта-обёртки, но таким образом, чтобы избежать любых новых проблем:

Мы можем легко переписать скрипт-обёртку для поддержки пользовательского GREP_OPTS, даже если GREP_OPTIONS не будет поддерживаться (поскольку он уже устарел). Таким образом, пользователи могут просто добавить export "GREP_OPTIONS=--color=auto" или подобное в свой профиль. /usr/local/bin/grep - тогда

#!/bin/sh
exec /bin/grep $GREP_OPTIONS "$@"

Обратите внимание, что вокруг $GREP_OPTIONS нет кавычек, так что пользователи могут указать более одной опции.

На моей системе выполнение time /usr/local/bin/grep --version с GREP_OPTIONS пустым, или с GREP_OPTIONS=--color=auto, происходит так же быстро, как и предыдущая версия сценария-обертки; т.е. обычно на выполнение уходит на одну миллисекунду больше, чем у обычного grep.

Эта последняя версия - та, которую я лично рекомендую использовать.


В итоге, стратегия OP 4:

  • уже рекомендована разработчиками grep

  • тривиальна в реализации (две строки)

  • имеет незначительные накладные расходы (одна миллисекунда дополнительной задержки на вызов на этом конкретном ноутбуке; легко проверяется на каждой машине)

  • может быть реализован в виде скрипта-обертки, добавляющего поддержку GREP_OPTS (для замены устаревших/неподдерживаемых GREP_OPTIONS)

  • может быть реализована (как colorgrep/cgrep), что совершенно не влияет на скрипты или существующих пользователей

Потому что это техника, которая уже широко используется в дистрибутивах Linux, это обычная техника и не "грязная".

Если она реализована как отдельная обертка (colorgrep/cgrep), она не может создать новых проблем, поскольку не влияет на поведение grep. Если это реализовано как сценарий-обёртка, добавляющий поддержку GREP_OPTS, использование GREP_OPTS=--color=auto имеет точно такие же риски (относительно проблем с существующими сценариями), что и добавление по умолчанию --color=auto. Таким образом, замечание о том, что это "создаёт больше проблем, чем решает", совершенно неверно: никаких дополнительных проблем не создаётся.

13
27.01.2020, 20:00

Я понимаю, что это старый вопрос, но для решения Стратегии 3:

Strategy 3: alias. This does not work for find... | xargs grep, since xargs does not evaluate aliases.

Изhelp alias:

alias: alias [-p] [name[=value]... ]
    A trailing space in VALUE causes the next word to be checked for
    alias substitution when the alias is expanded.

Поэтому создайте псевдоним для xargsс завершающим пробелом:

alias xargs='xargs '
alias chgrep='\grep --color=auto --include=\*.{c,cc,cpp,h,hh,hpp} -r'

find /path/ -type f | xargs chgrep 'foo'
1
13.10.2020, 15:40

Теги

Похожие вопросы