Пользователь MelBurslan ответил в комментарии под на этот более общий вопрос (Возможно ли чтобы указать путь, в котором один из уровней каталогов является переменным?) :
пока изменяющийся уровень каталогов является одним каталогом, что я подразумеваю под этим, если у вас есть / dir1 / dirX / dir3 / dir4, а часть dirX не меняется, как dirX / dirY / dirZ, но может быть только одним из dirX, dirY или dirZ, тогда вы можете ссылаться на / dir1 / dirX / dir3 / dir4 как / dir1 / * / dir3 / dir4
Итак, в приведенном выше случае команда, которая работает, выглядит примерно так: mpv / media / username / * / VIDEO_TS
С 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. Вы можете использовать:
awk '$2 == "Turtle" {print $1}' file
259497
457032
не -awk альтернатива:
grep -w "Turtle" turtle.txt | cut -d " " -f 1
Вы можете использовать grep
в этом:
grep -oP '^\d+(?=\h+Turtle\h)'
$ 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
.