Получить строку из файла - PullRequest
1 голос
/ 06 февраля 2012

В моем файле пакетов у меня есть несколько пакетов.Я могу проверить файл, если строка находится внутри, и если да, я хотел бы получить версию файла.

Package: depictiontest
Version: 1.0
Filename: ./debs/com.icr8zy.depictiontest.deb
Size: 810
Description: Do not install. Testing Depiction.
Name: Depiction Test

, поэтому приведенное выше является частью многих похожих сведений оупаковка.Каждый раз, когда я определяю, существует ли пакет, я хотел бы получить версию.Есть ли какой-нибудь возможный способ?

Кстати, это то, что я использую, чтобы проверить, существует ли файл.

if grep -q "$filename" /location/Packages; then
#file exists
#get file version <-- stuck here
else
#file does not exists
fi

РЕДАКТИРОВАТЬ: Извините, но, возможно, я не ясно объяснил,У меня уже есть Имя пакета и я хотел бы извлечь только версию этого пакета.Мне не нужен цикл, чтобы получить все имена и версии.Надеюсь, это все прояснит ...:)

Ответы [ 5 ]

2 голосов
/ 06 февраля 2012

Как вы извлекаете имя файла в первую очередь? Почему бы не проанализировать весь файл, а затем отфильтровать несуществующие имена файлов.

awk '/^Package:/{p=$2}
    /^Version:/{v=$2}
    /^Filename:/{f=$2}
    /^$/{print p, v, f}' Packages |
while read p v f; do
    test -e "$f" || continue
    echo "$p $v"
done

Это не надежно, например, имена файлов с пробелами, но файлы пакетов в любом случае не имеют имен файлов с пробелами. (Ваш пример файла имени нестандартный; давайте предположим, что он не хуже этого.)

Вы хотите убедиться, что в конце пакета есть пустая строка, или принудительно наберите { sed '$/^$/d' Packages; echo; } | awk ...

Редактировать: Предполагается, что файл Packages довольно хорошо сформирован с пустой строкой между записями. Если в записи отсутствует одно из этих полей, вывод будет повторять значение из предыдущей записи - это неприятно. Если есть несколько смежных пустых строк, он выведет один и тот же пакет дважды. И т.д. Если вы хотите надежный анализ, я бы переключился на Perl или Python или использовал стандартный инструмент Debian (я уверен, что он должен быть).

1 голос
/ 07 февраля 2012

С помощью grep вы можете выбрать определенное количество строк до или после ключевого слова.

egrep -A1 "^Package: depictiontest" /path/to/file

даст 1 дополнительную строку после совпадения.

egrep -B1 "^Filename: .*depictiontest.*" /path/to/file

даст 1 дополнительную строку до совпадения.

egrep "^(Package|Version): " "^Package: depictiontest" /path/to/file

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

0 голосов
/ 07 февраля 2012

Самая простая awk реализация, которую я могу придумать:

$ awk -F':' -v package='depictiontest' '
$1 == "Package" {
    trimmed_package_name = gensub(/^ */, "", "", $2)
    found_package = (trimmed_package_name == package)
}

found_package && $1 == "Version" {
    trimmed_version_number = gensub(/^ */, "", "", $2)
    print trimmed_version_number
}
' Packages
1.0

Это обрабатывает файл (Packages) построчно и устанавливает флаг found_package, если строка начинается с «Package» и значения после разделителя полей (-F), которое равно : (и любые пробелы) - это значение, переданное в переменную package (-v). Затем, если флаг установлен и мы находим строку, начинающуюся с поля «Версия», мы печатаем значение после разделителя полей (обрезание начальных пробелов). Если найдено другое поле «Пакет» и имя не совпадает с тем, которое мы ищем, флаг сбрасывается, и последующий номер версии не печатается.

0 голосов
/ 06 февраля 2012

Если порядок такой же, то вы можете проанализировать весь файл и передать значения в массив -

awk -F": " '
/^Package/{p=$2;getline;v=$2;getline;f=$2;ary[p"\n"v"\n"f"\n"]}
END{for (x in ary) print x}' file

Тест:

[jaypal:~/Temp] cat file
Package: depictiontest
Version: 1.0
Filename: ./debs/com.icr8zy.depictiontest.deb
Size: 810
Description: Do not install. Testing Depiction.
Name: Depiction2fdf Test
Package: depi444ctiontest
Version: 1.05
Filename: ./debs/coffm.icr8zy.depictiontest.deb
Size: 810
Description: Do not install. Testing Depiction.
Name: Depiction Test
Package: depic33tiontest
Version: 1.01
Filename: ./d3ebs/com.icr8zy.depictiontest.deb
Size: 810
Description: Do not install. Testing Depiction.
Name: Depiction Test

[jaypal:~/Temp] awk -F": " '/^Package/{p=$2;getline;v=$2;getline;f=$2;ary[p"\n"v"\n"f"\n"]}END{for (x in ary) print x}' file
depi444ctiontest
1.05
./debs/coffm.icr8zy.depictiontest.deb

depic33tiontest
1.01
./d3ebs/com.icr8zy.depictiontest.deb

depictiontest
1.0
./debs/com.icr8zy.depictiontest.deb
0 голосов
/ 06 февраля 2012

Если строка «Version: ...» всегда ровно на 1 строку перед строкой «Filename: ...», то вы можете попробовать что-то вроде этого:

line_number=$(grep -n "$filename" /location/Packages | head -1 | cut -d: -f1)
if (( $line_number > 0 )); then
  #file exists
  version=$(head -n $(( $line_number - 1 )) /location/Packages | tail -1 | cut -d' ' -f2)
else 
  #file doesn't exist
fi
...