Поиск с помощью opkg

Хорошо, давайте вернемся и посмотрим, что вы пытаетесь сделать. Первое, что нужно понять, это то, что вы не хотите проверять, является ли имя файла «*.txt», вы хотите увидеть, соответствует ли оно шаблону «*.txt». Кроме того, есть несколько различных шаблонов, с которыми вы столкнетесь в сценариях Unix; наиболее распространенными являются подстановочные знаки (или шаблоны "glob" )и регулярные выражения (, а также существует ряд версий синтаксиса регулярных выражений ). Здесь у вас есть шаблон глобуса.

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

Во-вторых, вы используете это в операторе if. Условное в операторе if(вещь между ifиthen)является командой(или, по крайней мере, командой -, подобной вещи ). Оператор ifзависит от того, будет ли эта команда выполнена успешно или нет. Одной из наиболее часто используемых команд в операторах ifявляется [, которая представляет собой команду, подобную этой:

if [ "$file" = "*.txt" ]; then

[выглядит как какой-то синтаксис оболочки или странная скобка, но это не так, это обычная команда (, в основном эквивалентная команде test). Но это обычная команда, которая требует, чтобы ее последний аргумент был снова " ]" (, не совсем закрывающая скобка, просто обычный аргумент команды ), и анализирует остальные аргументы как логическое выражение. См. man [для его синтаксиса. Кроме того, обратите внимание, что я дважды -цитировал как "$file", так и "*.txt", потому что (в качестве обычных аргументов команды )имя файла будет подвергаться разбиению на слова, и они оба будут подвергаться расширению с помощью подстановочных знаков, что может сеять хаос с синтаксисом выражения.

Но [не выполняет сопоставление с образцом. Он может выполнять строковые и числовые (целочисленные )сравнения, но не сопоставление с образцом. Поэтому нам нужно искать в другом месте.

Если вы используете bash (или zsh или даже ksh, но не dash или другую более простую оболочку ), вы можете использовать [[ ]]. В отличие от [, этот представляет собой синтаксис оболочки вместо обычной команды и, по сути, является очищенной -и обновленной заменой [. И он может выполнять сопоставление с образцом с оператором =, если вы оставите правую часть без кавычек. То есть,это будет выполнять буквальное сравнение строк:

if [[ "$file" = "*.txt" ]]; then

И это будет выполнять исправление шаблона глобуса:

if [[ "$file" = *.txt ]]; then

(Обратите внимание, что на самом деле вам не нужно удваивать -кавычки $fileдля любого из них, но я предпочитаю автоматически удваивать -ссылки на переменные кавычек на том основании, что почти всегда безопасно удваивать -заключать их в кавычки, часто небезопасно оставлять их без кавычек, и легче запомнить исключения, в которых они должны быть не в кавычках, чем те, где они должны быть в кавычках.)

Итак, эта последняя команда является возможным ответом для вас при условии , что вы используете оболочку, которая поддерживает [[ ]](, т.е. если вы используете bash shebang, например #!/bin/bashили #!/usr/bin/env bash, не общий sh ).

Если вы используете простую sh, нам придется немного изменить правила. Самый простой способ выполнить сопоставление шаблонов с подстановочными знаками в общей оболочке POSIX — использовать caseвместо if. И это нормально, потому что сопоставление шаблонов с подстановочными знаками — это то, для чего caseбыл создан :

.
case "$file" in
    *.txt )
        echo "File is in correct format." ;;

    * )
        "File is not in correct format. Please recheck your file." ;;
esac

Обратите внимание, что шаблон *(, который соответствует всему, что не соответствует более раннему шаблону ), действует подобно предложению elseв операторе if. Кроме того, к синтаксису нужно немного привыкнуть: )между каждым шаблоном и командой (s )для выполнения, если он совпадает, и ;;в конце команд каждого шаблона.

Есть и другие варианты, если мы переключимся с «Я хочу сопоставить шаблон глобуса» на «Я хочу увидеть, заканчивается ли имя файла на '.txt'». Есть несколько (POSIX -стандартных )способов сделать это с помощью модификаторов расширения имени файла. Например, ${var%pattern}удалит совпадение patternс конца значения переменной (, если соответствует ). Итак, один из стандартных приемов — попытаться удалить «.txt» в конце имени файла и посмотреть, изменилось ли оно. Если да, то ".txt" совпадал; если нет, то не было.Вот так:

if [ "$file" != "${file%.txt}" ]; then

Обратите внимание, что здесь используется проверка не -равенства (!=), потому что строки будут отличаться только в том случае, если «.txt» был успешно удален с конца.

Вы также можете удалить последний "." в имени файла с${file##*.}(и посмотрите, осталось ли «txt» ), но проблема в том, что он будет думать, что имя файла «txt» совпадает. Упс.

0
10.01.2021, 16:17
2 ответа

Для поиска доступных пакетов используйте:

opkg list | grep package

или

opkg list *package*

searchиспользование вopkg:

opkg search file    

Список пакетов, предоставляющих file.

opkgсправочные страницы:

   search <file|regexp>    List package providing <file>
0
18.03.2021, 22:37

Команда opkg searchошибочно заявляет, что ожидает регулярное выражение regexp (). На самом деле он ожидает подстановочный знак оболочки glob (). Кроме того, шаблон во многом соответствует всему пути и ищет только в базе данных установленных пакетов.

Итак, в одном из моих QNAP

opkg search /opt/bin/find    # "findutils - 4.7.0-1"
opkg search find             # no match
opkg search '*/find'         # "findutils - 4.7.0-1"

Но

opkg search '*/ls'           # no match, because coreutils-ls is not installed

Если вы хотите узнать, какой пакет содержит файл, сделать это не так-то просто. Вы можете искать имена пакетов,

opkg list | grep vi
opkg list | awk '$1 ~ /\<vi/'

или искать визуально,

opkg list | sort | cut -c1-80 | less
0
18.03.2021, 22:37

Теги

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