Как получить конкретную строку с помощью команды вырезать? - PullRequest
1 голос
/ 30 мая 2019

Фон

У меня есть файл с именем yeet.d, который выглядит следующим образом

JET_FUEL = /steel/beams
ABC_DEF = /michael/jackson
....50 rows later....
SHIA_LEBEOUF = /just/do/it
....73 rows later....
GIVE_FOOD = /very/hungry
NEVER_GONNA = /give/you/up

Я знаком с параметрами f and d команды cut. Параметр f позволяет указать, из каких столбцов извлекать, а параметр d позволяет указать разделители.

Задача

Я хочу, чтобы этот вывод был возвращен с помощью команды cut.

/just/do/it

Насколько я знаю, это часть команды, которую я хочу ввести:

cut -f1 -d= yeet.d

Учитывая, что я хочу получить значения справа от знака равенства со знаком равенства в качестве разделителя. Однако это вернет:

/steel/beams
/michael/jackson
....50 rows later....
/just/do/it
....73 rows later....
/very/hungry
/give/you/up

Что больше, чем я хочу.

Вопрос

Как использовать команду cut для возврата только /just/do/it и ничего другого из описанной выше ситуации? Это отличается от Как получить второе последнее поле из команды вырезания , потому что я хочу выбрать строку в большом файле, а не только рядом с концом или началом.

Ответы [ 2 ]

2 голосов
/ 30 мая 2019

Похоже, было бы проще выразить с помощью awk ...

# awk -v _s="${_string}" '$3 == _s {print $3}' "${_path}"

## Above could be more _scriptable_ form of bellow example

awk -v _search="/just/do/it" '$3 == _search {print $3}' <<'EOF'
JET_FULE = /steal/beams
SHIA_LEBEOUF = /just/do/it
NEVER_GONNA = /give/you/up
EOF

## Either way, output should be similar to
##  /just/do/it
  • -v _something="Some Thing" бит позволяет передавать переменные Bash в awk

  • $3 == _search бит сообщает awk о соответствии, только если столбец 3 равен search строке

    • Для поиска подстроки в строке можно использовать $0 ~ _search
  • {print $3} бит сообщает awk - print столбец 3 для любых совпадений

  • И бит <<'EOF' говорит Bash не расширять что-либо в пределах открывающих и закрывающих EOF тегов

... однако, выше все равно будет выводить дубликаты совпадений, например. если yeet.d как-то содержится ...

JET_FULE = /steal/beams
SHIA_LEBEOUF = /just/do/it
NEVER_GONNA = /give/you/up
AGAIN = /just/do/it

... было бы две /just/do/it строки с awk.

Самый быстрый способ обойти это было бы по каналу | до head -1, но способ лучше состоит в том, чтобы передать awk до exit после того, как ему было сказано print .. .

_string='/just/do/it'
_path='yeet.d'

awk -v _s="${_string}" '$3 == _s {print $3; exit}' "${_path}"

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


Обновление

To Отключение awk по первому столбцу при печати третьего столбца и выход из первого совпадения может выглядеть следующим образом ...

_string='SHIA_LEBEOUF'
_path='yeet.d'

awk -v _s="${_string}" '$1 == _s {print $3; exit}' "${_path}"

... и обобщать еще дальше ...

_string='^SHIA_LEBEOUF '
_path='yeet.d'

awk -v _s="${_string}" '$0 ~ _s {print $3; exit}' "${_path}"

... потому что awk полностью получает регулярных выражений, в основном .

1 голос
/ 30 мая 2019

Зависит от того, как вы хотите определить нужную строку.

Вы можете идентифицировать его по номеру строки. В этом случае вы можете использовать sed

cut -f2 -d= yeet.d | sed '53q;d'

Это извлекает 53-ю строку.

Или вы можете определить его по ключевому слову. В этом случае используйте grep

cut -f2 -d= yeet.d | grep just

Это извлекает все строки, содержащие слово просто .

...