Подобный DropFuse, у Вас есть также FuseDropbox: http://sourceforge.net/projects/fusedropbox/
Не совсем подходит для больших файлов, но 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
Вы можете вставить вывод из разных команд под разными номерами строк, просто помните , что вам нужно работать в обратном направлении, когда ed
iting through line number addresses:
ed -s desired.txt <<IN
48r !grep "another_key" another_temp_file
4r !grep "key" temp_file
w
q
IN
Я не понимаю, почему все пытаются сделать неприятности от простой задачи?
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
$ SED '4 A \
> `GREP" Клавиша "temp_file`' fized.txt
Попробуйте это. Вариант A
предназначен для после строки нет. 4. Вы также можете дать вариант I
для отсутствия строки. 4
Надеюсь, это должно работать.
Здесь решение 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}
)
Если вы правильно рассчитываете время своих шагов, это может быть довольно легко. Наиболее важно получить буфер исходного файла, который не взорвется при перегрузке. Единственный реальный способ сделать это - использовать другой файл, и оболочка делает это очень легко.
{ 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 <>
важно - оно устанавливает O_RDWR в stdout и гарантирует, что при записи в файл каждый процесс перезаписывает предыдущее содержимое файла. Другими словами, это означает, что исходный / целевой файл никогда не усекается, а скорее переписывается с головы до пят. exec
выполняет часть racy как можно скорее (или как только я знаю) . В подгруппе команд noclobber установлен
, поэтому, если «$ {TMPDIR: - / tmp} / $$»
уже существует, раскрытие результатов в exec <"$ {TMPDIR: - / tmp} /"
, который в интерактивной оболочке сразу же остановит весь процесс, или, в сценарии, вызовет завершение сценария со значимой ошибкой, поскольку оболочка не может exec
каталог как стандартный ввод. cat
копирует исходный_файл
во временный файл, который еще не существует, а echo
записывает имя в стандартный вывод. exec
ed rm
unlink ()
, они станут новым временным файлом, так что его единственное мимолетное утверждение о существовании сейчас - <
только что назначенное перенаправление. head
перебирает строки размером 2,5 мил и записывает первые строки размером 2,5 мил source_file
. Дело в том, чтобы искать в обоих файлах равные смещения.
head
читается из файла на диске и записывается в файл в RAM. exec <> "$ (... head ...<& 1> & 0
, чтобы сделать файл tmp доступным для чтения / записи и, возможно, использовать head
/ tail
с указанным количеством строк в конце. В этом случае число даже не обязательно должно быть точным - вы можете перебрать в цикле ввод аналогичным образом - увеличивая смещение только немного за раз. Встроенная оболочка read
может использоваться для проверки EOF - или wc
может использоваться при разомкнутом цикле. cat
, вероятно, просто зависнет на <>
stdin, потому что он никогда не увидит EOF. grep
считывает некоторые данные из другого файла и записывает их в исходный_файл
, перезаписывая только то количество байтов, которое было прочитано из другого места. cat
исправляет любое несоответствие grep
, которое могло быть вызвано только записью того, что осталось от его stdin, в его stdout 1 <> source_file
. Если желаемый.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