перенаправить вывод на определенный номер строки

Я хочу grep определенные строки по keyword и перенаправить вывод на определенный номер строки существующего файла.

команда

 grep "key" temp_file >> desired.txt 

Мне нужно, чтобы я мог добавить строки grepped к определенному номеру строки, например, x файла desired.txt

  • Как установить неограниченный размер в файл истории для tcsh?
  • В tcsh как я могу добавить «cd» к выходу канала?
  • Разница в поведении tcsh / vi-mode между Solaris и Linux
  • Совместимость скриптов: Сохранить $? для использования позже
  • Выход из программы завершения tcsh по программе
  • Глобальный / etc / profile setenv или экспорт, перезаписывающий пользовательские настройки в .profile
  • Как изменить дерево дерева каталогов по записи
  • настроить цвет ls для каталогов содержат указанные файлы / с
  • 6 Solutions collect form web for “перенаправить вывод на определенный номер строки”

    Если вы выполняете правильные шаги, это может быть довольно легко. Самое главное – получить буфер исходного файла, который не будет взорваться при перегрузке. Единственный реальный способ сделать это – с другим файлом, который оболочка делает очень легко.

     { head -n "$((num_lines_before_insert))" grep key temp_file; sed \$d } <<SOURCE_FILE >desired.txt $( cat <source_file;echo .) SOURCE_FILE 

    Таким образом, для большинства оболочек (включая bash и zsh , но не dash или yash ), когда вы получаете << here_document, оболочка создает файл с уникальным именем temp в ${TMPDIR:-/tmp} , exec s it на входе дескриптор файла, который вы указываете, – (или, по умолчанию, всего 0) – и быстро удаляет его. К тому времени, когда он будет использоваться в качестве входных данных для вашей команды, это файл без имени – он не имеет оставшихся ссылок на любую файловую систему и просто ждет, пока ядро ​​его очистит, прежде чем оно полностью исчезнет. Это правильный файл – его данные существуют где-то на диске (или, по крайней мере, в VFS в вероятном случае tmpfs ), и ядро ​​обеспечит его продолжение по крайней мере до тех пор, пока вы не отпустите дескриптор файла.

    Таким образом, пока ваша оболочка получает фактический файл поддержки для heredoc – они представляют собой очень безопасные и простые средства обработки временных файлов, потому что они полностью написаны, и все имена файловой системы уже удалены из них, прежде чем вы их прочитаете , Поэтому их данные нельзя подделать, пока вы работаете.

    Вышеупомянутый блок сначала записывает временный файл с cat и сохраняет любые / все конечные пустые строки из командной подстановки с помощью echo что добавляет одну строку в хвост файла. Из инструкции { составная команда } вывод трех трех команд записывается в desired.txt – два из которых считывают в свою очередь из heredocument head и хвост исходного файла – и команду grep которая вставляет ваш key .

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

    Если ваша оболочка не получает фактический файл для heredocs, вы можете эмулировать то, что ему нравится …

     { set "$$" "${TMPDIR:-/tmp}" "$@" exec <"$2/$( set -C >"$2/$1" cat && echo "$1")" >&1 rm -- "$2/$1";shift 2 head "-n$((before))" grep ... keyfile; cat } <source_file 1<>source_file 

    … который гарантирует, что все файлы будут доступны для записи и безопасно назначены файловым дескрипторам, прежде чем предпринимать какие-либо необратимые действия, но также сделает всю очистку файловой системы перед тем, как сделать это.

    Вот тест, который я проверил, чтобы продемонстрировать это:

     cd /tmp set "$$" "${TMPDIR:-/tmp}" "$@" seq 5000000 >test printf line\ %s\\n 1 2 3 4 5 >test2 { exec <"$2/$( set -C >"$2/$1" cat && echo "$1")" >&1 rm -- "$2/$1";shift 2 head -n2500000 grep 3 test2;cat } <test 1<>test 

    Сначала создавались два файла – один из них назывался /tmp/test который состоял всего из 5 миллионов пронумерованных строк, написанных seq а второй назывался /tmp/test2 который был всего 5 строк, таких как …

     line 1 line 2 line 3 line 4 line 5 

    Затем я побежал над этим блоком, потом сделал …

     sed -n '1p;$p;2499999,2500002l' <test wc -l test 

    … что, интересно, заняло практически такое же количество времени для выполнения операции вставки и напечатало:

     1 2499999$ 2500000$ line 3$ 2500001$ 5000000 5000001 test 

    Итак, вот как это работает:

    1. Перенаправление 1<> важно – он устанавливает флаг O_RDWR на stdout и гарантирует, что по мере того как каждый процесс записывает в файл, он записывает предыдущее содержимое файла. Другими словами, это означает, что ни в каком случае исходный / целевой файл никогда не усекается, а скорее переписывается с головы до хвоста.
    2. Замена команды для exec получает неотложную часть, как только это возможно (или как только я это знаю) . Внутри команды sub noclobber set так, что если "${TMPDIR:-/tmp}/$$" уже существует, то результат расширения в exec <"${TMPDIR:-/tmp}/" который в интерактивной оболочке прекратит весь процесс сразу, или, в сценарии, заставит скрипт выйти со значимой ошибкой, так как оболочка не может exec каталог как stdin.
    3. В пределах команды sub cat копирует source_file в временный файл, который еще не существует, и echo записывает имя в stdout.
    4. Как только все дескрипторы файлов исполняются rm unlink() s, новый временный файл, поэтому его единственным мимолетным заявлением о существовании теперь является < перенаправление, которое оно было просто назначено.
    5. head ищет по 2,5-миллиметровым линиям и записывает первые 2,5-миллилитровые строки source_file. Дело в том, чтобы искать оба файла равными смещениями.
      • Это напомнит, что эта часть может быть более эффективной в том случае, если вновь созданный файл tmp находится на tmpfs, а исходный файл находится на диске, если здесь были отменены операции ввода / вывода и начата запись из файла на диске и написана к файлу в ОЗУ.
      • Если вы хотите сделать это, хотя вам нужно будет выполнить exec <>"$(... head ... <&1 >&0 чтобы сделать файл tmp доступным для чтения / записи и, возможно, использовать head / tail с указанным количеством строк для хвоста. В этом случае число не обязательно должно быть точным – вы можете чередовать ввод аналогичным образом – продвигая смещение только немного за раз. Встроенное read оболочки можно использовать для проверки EOF – или wc может использовать при открытой петле.
      • Это потому, что cat , вероятно, просто повесится на <> stdin, потому что она никогда не увидит EOF.
    6. grep читает некоторые данные из другого файла и записывает их в source_file переписывая только столько байтов, сколько читает из других источников.
    7. cat исправляет любое несоответствие, которое grep может просто вызвать из-за написания того, что осталось от его stdin, до его 1<>source_file .

    Не подходит для огромных файлов, но ed может выводить команду и вставлять ее после адресной строки, например:

     ed -s desired.txt <<IN 4r !grep "key" temp_file w q IN 

    или, в одной строке:

     printf '%s\n' '4r !grep "key" temp_file' wq | ed -s desired.txt 

    Вы можете вставлять выходные данные из разных команд с разными номерами строк, просто имейте в виду, что вам нужно работать назад при редактировании по номерам номеров строк:

     ed -s desired.txt <<IN 48r !grep "another_key" another_temp_file 4r !grep "key" temp_file w q IN 

    Если desired.txt – очень большой файл, тогда вы можете оптимизировать его. Вероятно, это можно сделать более элегантным на уровне оболочки, но поскольку я не знаком с tcsh я предлагаю что-то, что должно там работать.

     sed -n '1,4p' desired.txt >file.tmp grep "key" temp_file >>file.tmp sed -n '5,$p' desired.txt >>file.tmp mv file.tmp desired.txt 

    Здесь awk решение (работает с любой оболочкой, mawk и gawk ):

     awk 'NR==3{ while((getline x<"test_file")>0) { if(x~/key/){print x} } } {print}' desired.txt 

    Результат: извлеченная строка будет напечатана в строке 3.

    Объяснение: В строке № 3 ( NR==3 ), петля через второй файл ( while((getline x<"test_file")>0) ), и если строка во втором файле содержит «ключ» ( if(x~/key/) ) напечатать эту строку ( {print x} ). Строка от файла desired.txt первого файла должна быть напечатана в любом случае ( {print} )

    Я не понимаю, почему каждый пытается сделать проблему из простой задачи?

     sed -i "4a$(grep "key" temp_file)" desired.txt 

    (изменение 4 для любого номера строки, который вам нужен)

    Или (для многострочного grep вывода)

     grep "key" temp_file > grepped.tmp sed -i '4r grepped.tmp' desired.txt 

    $ sed '4 a \

    > `grep" ключ "temp_file`" wish.txt

    Попробуй это. Вариант a для после строки №. 4. Вы также можете указать опцию i для строки №. 4

    Надеюсь, это должно сработать.

    Interesting Posts

    Есть ли файл Bash, который всегда будет использоваться в интерактивном режиме независимо от того, является ли он логином или недействительным?

    rsync с двоеточиями в именах файлов

    Почему autoconf.h не копируется автоматически на свое место?

    Как настроить набор компьютеров для netboot?

    Как заставить `less -FX 'играть хорошо с помощью командной строки с двумя строками

    Что изменяет mkinitrd при добавлении модулей ядра в initrd?

    Имеет ли смысл иметь отдельные объемы ubi для безопасности с ubifs?

    Может ли X11 масштабироваться до виртуальных разрешений на экранах HiDPI / Retina, как это делает OS X?

    Установите программу по умолчанию для типа MIME: image / *

    Как получить информацию с тем, что у меня есть сейчас?

    вкладка grep и символ звезды

    Разница между эхом и печатью в оболочке Korn

    Многопользовательская система Linux: домашний раздел каждого пользователя на собственном жестком диске

    glib-ошибки на cygwin

    Отправьте задачу на фоновый рисунок в «if»

    Linux и Unix - лучшая ОС в мире.