Извлечь значение m-го (первого) столбца для строки с конкретным значением n-го (второго) столбца из файла [дубликат]

Пользователь MelBurslan ответил в комментарии под на этот более общий вопрос (Возможно ли чтобы указать путь, в котором один из уровней каталогов является переменным?) :

пока изменяющийся уровень каталогов является одним каталогом, что я подразумеваю под этим, если у вас есть / dir1 / dirX / dir3 / dir4, а часть dirX не меняется, как dirX / dirY / dirZ, но может быть только одним из dirX, dirY или dirZ, тогда вы можете ссылаться на / dir1 / dirX / dir3 / dir4 как / dir1 / * / dir3 / dir4

Итак, в приведенном выше случае команда, которая работает, выглядит примерно так: mpv / media / username / * / VIDEO_TS

5
09.10.2018, 05:45
5 ответов

С awk:

$ awk '$2 == "Turtle" {print $1}' turtle.txt
259497
457032
  • $2— поле для выбора.
  • Turtle— текст для сопоставления.
  • {print $1}— распечатать первое поле.
  • turtle.txt— имя исходного файла.

С СЭД:

$ <infile sed -E 's/[[:blank:]]+/\n/g;/([^\n]+\n){1}Turtle/([^\n]*).*/\1/;p};d'

Объяснение:

  • <infileИсходный файл
  • sed -EИспользование sed с POSIX ERE (Расширенные регулярные выражения)
  • 's/[[:blank:]]+/\n/gЗаменить все (прогоны+)вкладки -новой строкой.
  • /([^\n]+\n){1}Turtle\n/Если в полеn(используйте n-1здесь )соответствуетTurtle(точно ).
  • ([^\n]*).*/\1/Извлечь поле 1 (первая строка)
  • p};d'Распечатать выбранное и удалить все в любом случае.

Общее решение для любой пары полей (s)nиm:

<infile sed -E 's/[[:blank:]]+/\n/g;/([^\n]+\n){1}Turtle/{s/([^\n]+\n){0}([^\n]*).*/\2/;p};d'
  • <infileИсходный файл
  • sed -E 'Для sed с регулярными выражениями ERE.
  • s/[[:blank:]]+/\n/gРазбейте весь ввод на строки в (прогонах )табуляций или пробелов.
  • /([^\n]+\n){1}Turtle/Если пространство шаблонов совпадает с n-м полем (, используйтеn-1({1})здесь ).
  • {Запустить последовательность команд.
  • s/Запустите команду замены (на s///).
  • ([^\n]+\n){0}Соответствиеm-1({0})строк (для поляm).
  • ([^\n]*)Захватите поле (строку )для сохранения обратной ссылки \2.
  • .*И сопоставьте все остальное (в пространстве шаблонов (с исходной строкой )).
  • /\2/Замените все вышеперечисленное (Пространство шаблона )тем, что было захвачено в \2.
  • ;p};Распечатайте. И закрыть последовательность команд.
  • dВ любом случае удалите пространство шаблона и начните заново.
  • 'Завершить команду sed.
5
27.01.2020, 20:32

Вы можете использовать:

awk '$2 == "Turtle" {print $1}' file
259497
457032
4
27.01.2020, 20:32

не -awk альтернатива:

grep -w "Turtle" turtle.txt | cut -d " " -f 1

2
27.01.2020, 20:32

Вы можете использовать grepв этом:

 grep -oP '^\d+(?=\h+Turtle\h)'
1
27.01.2020, 20:32

Игра в гольф:

$ awk '$2=="Turtle"&&$0=$1' <file
259497
457032

Или поэтапно расширять, пока мы не достигнем ответов Исаака и Горо

awk '$2 == "Turtle" && $0 = $1' <file

awk '$2 == "Turtle" { $0 = $1; print }' <file

awk '$2 == "Turtle" { print $1 }' <file

Эти три не являются точно эквивалентными, так как мой код для игры в гольф не напечатал бы число, если бы оно было равно нулю (результат $0=$1используется как условный ).


Вот правильное sedрешение, чтобы компенсировать описанную выше игру в гольф:

$ sed -n '/\<Turtle\>/s/[[:blank:]].*//p' <file
259497
457032

Он находит все строки, содержащие слово Turtle, а затем удаляет первый пробел или символ табуляции и все после него в этих строках перед их печатью (печать других строк запрещается-n).

\<и \>соответствуют начальной и конечной границам слова, так что \<Turtle\>соответствует только строке Turtle, а не, например. RedTurtle.

2
27.01.2020, 20:32

Теги

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