Есть команда в моем $PATH, но она не распознается, когда я использую sudo [duplicate]

Допущения

Входными данными является текстовый файл, содержащий строки (последовательности непустых символов) , разделенные последовательностями пустых символов. Каждая строка содержит определенное слово (известное во время выполнения) , за которым (не обязательно сразу) следует строка , которая является числом, напоминающим номер версии. (По-видимому, это означает только то, что оно начинается с цифры.)

Должна быть возможность указать слово для поиска в качестве параметра во время выполнения. Например, для поиска слова tech , мы должны иметь возможность сказать что-то вроде

word=tech

и позволить команде (или скрипту) использовать $ слово . Слово должно совпадать точно; например, «технология», «нанотехнология» и «технология» не должны совпадать. Слово должно содержать только буквы, цифры и _ (подчеркивание) - знаков пунктуации и, особенно, символов, которые являются специальными в регулярных выражениях. - может привести к нежелательным результатам. Для каждой подходящей строки команда должна выводить слово и число, разделенные пробелом (и никак иначе). Если файл содержит строки, которые не соответствуют этим предположениям (например, не содержат желаемое слово или какое-либо число), поведение не определено. В частности, такие несоответствующие строки можно просто игнорировать.

Для всех нижеприведенных команд предполагается, что $ word определено, как описано выше.

Примечание: каждую из этих команд можно сформулировать по-разному. В некоторых случаях различия незначительны.

grep

plain grep

Я не мог понять, как это сделать.

plain grep с помощником

Команда

grep    "\<$word\>\|\<[[:digit:]][[:graph:]]*\>"

будет соответствовать каждой строке, содержащей или слово ( \ ) или ( \ | ) число ( \ ). ( [[: graph:]] означает букву, цифру или знак препинания; т. Е. Что-либо, кроме пробела.) Вывод этой команды в режиме - цвет немного интересен:

colored grep output

grep -o "\<$word\>\|\<[[:digit:]][[:graph:]]*\>"

выводит каждую совпадающую строку - и только соответствующие строки - на отдельные строки:

tech
1.2
tech
1
tech
0.1
tech
10.1.3
tech
7.5
tech
8.0
tech
0.x
tech
1.3.x
tech
5.x
tech
2.0.4x

Итак, мы делаем

grep -o "\<$word\>\|\<[[:digit:]][[:graph:]]*\>" (input_file) | sed "/$word/ { N; s/\n/ / }"

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

tech 1.2
tech 1
tech 0.1
tech 10.1.3
tech 7.5
tech 8.0
tech 0.x
tech 1.3.x
tech 5.x
tech 2.0.4x

pcregrep

pcregrep -o1 -o2 --om-separator=' ' "\b($word)\b.*?\b(\d\S*)"

соответствует слову , а - числу ( \ b - это граница слова, \ d - цифра, а \ S - любой символ, кроме пробела), захват каждого из них в () группа. Затем он использует -o для вывода только совпадающих строк - но в pcregrep вы можете сказать -o1-o2 для вывода групп захвата 1 и 2. - om-separator = '' , очевидно, указывает, что помещать между строками.

Примечание: поскольку здесь используется . *? (нежадное соответствие), если в строке ввода несколько чисел, найдет первое . Остальные команды найдут последнюю.

sed

sed -n "s/.*\(\<$word\>\).*[[:blank:]]\(\<[[:digit:]][[:graph:]]*\).*/\1 \2/p"

Подобно команде pcregrep , она сопоставляет строки в группах захвата и затем выводит их как \ 1 \ 2 .

awk

awk -v the_word="$word" '
    {
        w=0             # Index of word
        n=0             # Index of number
        for (i=0; i<=NF; i++) {
                if ($i == the_word) w=i
                if (substr($i,1,1) ~ /[[:digit:]]/) n=i
        }
        if (w>0  &&  n>w) print $w, $n
    }'

Это ищет слово ( the_word ) и число (строку, первый символ которой является цифрой). Если он находит их обоих в указанном порядке, он печатает их обоих.

Примечание: это распознает слово, только если оно полностью автономно. Другие команды будут соответствовать ему, если он касается знаков препинания; например,

The cyber clock goes tech, tock …
This contains the word (tech) …
1
22.10.2016, 20:37
0 ответов

Теги

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