echo> file
был бы простым решением. Но как только вы удалили файл, это больше невозможно.
Но подождите! Поскольку вы используете файловую систему ext4, я предполагаю, что этот tar работает в Linux. (Некоторые, но не все другие варианты Unix допускают подобное решение.) В Linux вы все еще можете получить доступ к удаленному, но открытому файлу через / proc / PID / fd / FD
, где PID
- это идентификатор процесса, у которого открыт файл, а FD
- это дескриптор файла, через который открывается файл. Этот файл представляет собой символическую ссылку на файл, но это магическая ссылка. Он остается в силе, даже если файл удален. Если вы посмотрите на него с помощью ls -l
, вы увидите что-то вроде
/proc/1234/fd/4 -> /path/to/file (deleted)
, по всей видимости, неработающую ссылку, но вы действительно можете открыть этот файл. В частности,
вы можете обрезать его, используя что-то вроде :> / proc / 1234 / fd / 4
.
Если вы работаете в системе без / proc
, вы можете использовать отладчик, чтобы заставить сам процесс tar выполнить усечение за вас. Присоедините отладчик к процессу, затем заставьте его выполнить truncate (4)
, где 4 - дескриптор файла, из которого tar читает. Например, с GDB вы можете попробовать что-то вроде
$ ps
… find the PID of the tar process, e.g. 1234
$ lsof -p1234
… find the file descriptor that you want to act on, e.g. 4
$ gdb -pid 1234
…
(gdb) call truncate(4)
(gdb) detach
. Это может или не может запутать tar, поскольку он может отображать некоторую структуру данных, которую он использует, несовместимой, поэтому я рекомендую поэкспериментировать, прежде чем опробовать ее на практике.
Включая перенаправление в цикл, вы перезаписываете test.txt
при каждой итерации. Вместо этого вы можете использовать цикл, чтобы создать сценарий для sed
и обработать файл с ним только один раз :
for i in "${arr[@]}" ; do
printf 's/%s/ANON/g\n' "$i"
done | sed -r -f- /log > /test.txt
Или просто:
printf 's/%s/ANON/g\n' "${arr[@]}" | sed -r -f- /log > /test.txt
Обратите внимание, что он все еще может сломаться, если массив содержит символы со специальным значением в sed (, что может даже привести к уязвимости внедрения команд, если содержимое массива не полностью находится под вашим контролем ).
Я предполагаю, что вы хотите заменить все вхождения любого слова в вашем массиве arr
словом ANON
.
Ваш код работает отлично, но вы перезаписываете выходной файл для каждой итерации цикла, а это означает, что в конечном файле будет заменено только последнее слово в массиве.
Также существует потенциальная проблема, если какое-либо из слов содержит символы, которые могут быть интерпретированы как символы регулярного выражения, например *
и [
.
Было бы безопаснее проводить точное сравнение строк для каждой замены. Вы можете сделать это с помощьюawk
:
{
while (offset = index($0, str))
$0 = substr($0, 1, offset - 1) "ANON" substr($0, offset + length(str))
}
{ print }
Это заменит все вхождения значения str
строкой ANON
, даже если str
содержит символы регулярного выражения.
Чтение строк из файла (с дополнительным бонусом, заключающимся в том, что второй столбец файла строк с разделителями табуляции -содержит строку для замены на):
BEGIN { FS = "\t" }
NR == FNR { str[$1] = $2; next }
{
for (s in str) {
sl = length(s)
while (offset = index($0, s))
$0 = substr($0, 1, offset - 1) str[s] substr($0, offset + sl)
}
}
{ print }
Учитывая вкладку -строки с разделителями strings
как
*password* *redacted*
My Name Not really my name
... и текстовый файл file.txt
как
Password for the account belonging to My Name: *password*
... код awk выдаст
Password for the account belonging to Not really my name: *redacted*
при запуске как
awk -f script.awk strings file.txt