Входными данными является текстовый файл, содержащий строки (последовательности непустых символов) , разделенные последовательностями пустых символов. Каждая строка содержит определенное слово (известное во время выполнения) , за которым (не обязательно сразу) следует строка , которая является числом, напоминающим номер версии. (По-видимому, это означает только то, что оно начинается с цифры.)
Должна быть возможность указать слово для поиска в качестве параметра во время выполнения. Например, для поиска слова tech , мы должны иметь возможность сказать что-то вроде
word=tech
и позволить команде (или скрипту) использовать $ слово
.
Слово должно совпадать точно;
например, «технология», «нанотехнология» и «технология» не должны совпадать.
Слово должно содержать только буквы, цифры и _
(подчеркивание) -
знаков пунктуации и, особенно,
символов, которые являются специальными в регулярных выражениях. -
может привести к нежелательным результатам.
Для каждой подходящей строки
команда должна выводить слово и число,
разделенные пробелом (и никак иначе).
Если файл содержит строки, которые не соответствуют этим предположениям
(например, не содержат желаемое слово или какое-либо число), поведение
не определено.
В частности, такие несоответствующие строки можно просто игнорировать.
Для всех нижеприведенных команд предполагается, что
$ word
определено, как описано выше.
Примечание: каждую из этих команд можно сформулировать по-разному. В некоторых случаях различия незначительны.
grep
grep
Я не мог понять, как это сделать.
grep
с помощником Команда
grep "\<$word\>\|\<[[:digit:]][[:graph:]]*\>"
будет соответствовать каждой строке, содержащей или слово ( \
)
или ( \ |
) число ( \
).
( [[: graph:]]
означает букву, цифру или знак препинания;
т. Е. Что-либо, кроме пробела.)
Вывод этой команды в режиме - цвет
немного интересен:
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) …