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

Подобный DropFuse, у Вас есть также FuseDropbox: http://sourceforge.net/projects/fusedropbox/

3
05.02.2015, 00:06
6 ответов

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

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

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

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

Вы можете вставить вывод из разных команд под разными номерами строк, просто помните , что вам нужно работать в обратном направлении, когда editing through line number addresses:

ed -s desired.txt <<IN
48r !grep "another_key" another_temp_file
4r !grep "key" temp_file
w
q
IN
1
27.01.2020, 21:23

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

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

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

или (для Multy-Line GREP Выход)

grep "key" temp_file > grepped.tmp
sed -i '4r grepped.tmp' desired.txt
0
27.01.2020, 21:23

$ SED '4 A \

> `GREP" Клавиша "temp_file`' fized.txt

Попробуйте это. Вариант A предназначен для после строки нет. 4. Вы также можете дать вариант I для отсутствия строки. 4

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

-1
27.01.2020, 21:23

Здесь решение awk решение (работает с любым оболочкой, Mawk и GAWK Тестируют):

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

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

Объяснение: в строке № 3 ( NR == 3 ), петли через второй файл ( пока (((getline x <"test_file") 0) ) и если линия во втором файле содержится «клавиша» (, если (x ~ / ключ /) ) Распечатайте эту строку ( {print x} ). Линия OT Первый файл lede.txt должен быть напечатан в любом случае ( {Print} )

0
27.01.2020, 21:23

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

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

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

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

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

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

Если ваша оболочка не получает фактический файл для 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 выполняет часть racy как можно скорее (или как только я знаю) . В подгруппе команд noclobber установлен , поэтому, если «$ {TMPDIR: - / tmp} / $$» уже существует, раскрытие результатов в exec <"$ {TMPDIR: - / tmp} /" , который в интерактивной оболочке сразу же остановит весь процесс, или, в сценарии, вызовет завершение сценария со значимой ошибкой, поскольку оболочка не может exec каталог как стандартный ввод.
  3. Внутри команды sub cat копирует исходный_файл во временный файл, который еще не существует, а echo записывает имя в стандартный вывод.
  4. Как только все дескрипторы файлов станут exec ed rm unlink () , они станут новым временным файлом, так что его единственное мимолетное утверждение о существовании сейчас - < только что назначенное перенаправление.
  5. head перебирает строки размером 2,5 мил и записывает первые строки размером 2,5 мил source_file . Дело в том, чтобы искать в обоих файлах равные смещения.
    • Помните, что эта часть могла бы быть более эффективной в отношении ввода-вывода, если вновь созданный файл tmp находится в tmpfs, а исходный файл находится на диске, если ввод-вывод был здесь перевернуто, и head читается из файла на диске и записывается в файл в RAM.
    • Если вы хотите это сделать, вам нужно будет выполнить exec <> "$ (... head ...<& 1> & 0 , чтобы сделать файл tmp доступным для чтения / записи и, возможно, использовать head / tail с указанным количеством строк в конце. В этом случае число даже не обязательно должно быть точным - вы можете перебрать в цикле ввод аналогичным образом - увеличивая смещение только немного за раз. Встроенная оболочка read может использоваться для проверки EOF - или wc может использоваться при разомкнутом цикле.
    • Это потому, что cat , вероятно, просто зависнет на <> stdin, потому что он никогда не увидит EOF.
  6. grep считывает некоторые данные из другого файла и записывает их в исходный_файл , перезаписывая только то количество байтов, которое было прочитано из другого места.
  7. cat исправляет любое несоответствие grep , которое могло быть вызвано только записью того, что осталось от его stdin, в его stdout 1 <> source_file .
3
27.01.2020, 21:23

Если желаемый.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
0
27.01.2020, 21:23

Теги

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