Выполните операции sed с заданными номерами строк

8

Мне интересно, есть ли простой способ работать на определенных линиях с предварительно назначенными номерами строк.

Допустим, я хочу вывести 1, 7, 14 и 16 строки файла, я могу просто сделать

sed -n '1p;7p;14p;16p' input_file

но это усложняется, когда операция не просто печатает, и я не хочу писать одну и ту же длинную команду 4 раза (и да, я знаю, что могу создать эту длинную команду sed, подставив одну и ту же переменную bash 4 раза, но это не достаточно идеально ...), т.е.

sed -n '1{long_command};7{long_command};14{long_command};16{long_command}' input_file

Есть ли способ сделать операцию над этими конкретными строками моего файла? Я ожидаю что-то вроде,

sed -n '1,7,14,16p'

что, конечно, не будет работать в текущей форме.

Любая помощь будет оценена. "Нет, это невозможно." с объяснениями тоже ответ, который я приму.

Вейцзюнь Чжоу
источник
это легко сawk
RomanPerekhrest

Ответы:

11

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

sed '
  1b1
  7b1
  14b1
  16b1

  # for the rest to be left alone, branch off (or delete them with "d"):
  b

  :1
  long_command'

(обратите внимание, что вы также можете добавить некоторые 20,25b1диапазоны строк или /re/b1включить строки, которые соответствуют re).

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

awk 'NR == 1 || NR == 7 || ... {stuff}'

Или используя хеш:

awk -v l=1,7,14,16 '
  BEGIN{split(l, a, ","); for (i in a) lines[a[i]]}

  NR in lines {stuff}'

(или BEGIN{lines[1]lines[7]lines[14]lines[16]}если их не слишком много)

Стефан Шазелас
источник
Спасибо, никогда не думал о ветвях ... Это просто идеальный инструмент для использования в этом случае.
Вейцзюнь Чжоу
как использовать такие ветки в sed с шаблоном поиска? как сказать, я хочу сопоставить или удалить шаблон после n-й строки?
qodeninja
3

Просто инвертируйте свой выбор и удалите его:

sed '2,6d;8,13d;15d;17,$d;long_command'
Philippos
источник
Это также хорошее решение, хотя и немного сложнее для обработки номеров строк, которые считываются, например, из stdin.
Вейцзюнь Чжоу
1

Первый вариант:

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

sed -nf <(printf '%dp\n' 1 7 14 16)

-f скрипт-файл - добавить содержимое скрипта-файла в команды, которые будут выполнены.

тестирование

seq 1 20 | sed -nf <(printf '%dp\n' 1 7 14 16)

Вывод

1
7
14
16

Второй вариант:

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

sed -n '1p; 7p; 14p; 16p' input.txt | sed 'long command'
MiniMax
источник