Как найти несколько строк?

perl -F'\t+' -lane '
   @ARGV and $h{$F[0]}++,next;
   print ">", join("\t", @F[2..5,-4..-1]), $\, $F[9] if exists $h{$F[2]};
' whitelist.txt batch_1.catalog.tags.tsv

Предположим, что ваш файл разделен TAB -.

Обратите внимание, что если в вашем файле могут быть окончания строк windows или mac, разумно сначала преобразовать их в окончания строк unix ("\n" )с помощью утилит dos2unix и т. д. Потому что много раз это было видно, что предоставленный код не работает в конце OP по подобным причинам.

Выработки

  • Обратите внимание, когда Perlобрабатывает первый аргумент (, в данном случае whitelight.txt, тогда @ARGV содержит batch_1.catalog.tsvфайл, т. е. @ARGV = 1 => @ARGV оценивается как ИСТИНА в логическом контексте..
  • @ARGV and $h{$F[0]}++,nextследует интерпретировать как :, когда мы обрабатываем файл белого света, затем добавляем первое поле($F[0])этого файла к хешу %hи сразу переходим к следующей строке.
  • Любые строки ниже этих будут обрабатывать TSV-файл, так как в это время @ARGV ничего не содержит, поэтому счетчик равен нулю.
  • Только те записи файла TSV должны перейти в стандартный вывод, третье поле которых $F[2]является ключом в хэше %h.
  • После принятия решения о печати записи TSV формат для ее печати:(Примечание :Значение по умолчанию OFSдля печати —NULL)
  • ">", $F[2]означает, что 3-му полю предшествует>
  • поля 4,5,6 => @F[3..5]будут разделены и объединены с помощью TAB.
  • последние 4 поля => @F[-4..-1]будут разделены и объединены с помощью TAB.
  • Десятому полю $F[9]будет предшествовать новая строка, которая обеспечивается $\= ORS= \nиз-за опции Perl-l.
1
31.07.2019, 02:01
1 ответ

Он понимает это хорошо, но не так, как вам хотелось бы. Фрагмент регулярного выражения {*соответствует нулю или более символам {, а n*соответствует нулю или более символам n, поэтому полное выражение {*clipper-coin*}будет соответствовать {clipper-coin}, {{{clipper-coi}или clipper-coinnnnnn}и т. д.

Линии -ориентированные утилиты обработки текста -, такие как большинство утилит в стандартном наборе инструментов Unix для обработки текста -, являются плохими инструментами для анализа структурированных данных, таких как JSON (, даже если они расширены дополнительными функциями для удобство для команд GNU и других ). Скорее всего, вместо этого вы захотите использовать парсер JSON.

Чтобы проанализировать возвращенный документ JSON для любого id, то естьbitcoin(я не вижу clipper-coinв выходных данных с этого сервера ), используйте анализатор JSON, напримерjq:

$ curl -s 'https://api.coinmarketcap.com/v1/ticker/' | jq '.[] | select(.id == "bitcoin")'
{
  "id": "bitcoin",
  "name": "Bitcoin",
  "symbol": "BTC",
  "rank": "1",
  "price_usd": "9626.82712316",
  "price_btc": "1.0",
  "24h_volume_usd": "13830555865.2",
  "market_cap_usd": "171817319309",
  "available_supply": "17847762.0",
  "total_supply": "17847762.0",
  "max_supply": "21000000.0",
  "percent_change_1h": "0.46",
  "percent_change_24h": "1.02",
  "percent_change_7d": "-3.11",
  "last_updated": "1564526372"
}

Выражение jq.[] | select(.id == "bitcoin")будет фильтровать возвращаемый массив JSON для элементов, чей ключ idсоответствует значению bitcoin.

Чтобы выбрать, например. значение price_usdиз этого, используйте

$ curl -s 'https://api.coinmarketcap.com/v1/ticker/' | jq '.[] | select(.id == "bitcoin").price_usd'
"9630.84837853"

Чтобы избавиться от кавычек, используйте jq -rвместо jq.

См. также руководство jq.

С jqвы также можете легко делать сложные запросы, такие как этот,который получает символ записи с наибольшим percent_change_1hзначением:

$ curl -s 'https://api.coinmarketcap.com/v1/ticker/' | jq 'max_by(.percent_change_1h | tonumber).symbol'
"WAX"
4
27.01.2020, 23:17

Теги

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