Удаление файла, в свою очередь, приводит к выполнению системного вызова vfs_unlink, а затем fs-специфического fs_unlink. Именно эти вызовы добираются до родительского каталога и удаляют inode соответствующего файла, в результате чего его дентри становится отрицательным. Данные на диске (какого бы размера они ни были) остаются как есть, с единственным изменением: блок, в котором они находятся, перемещается в банк свободных блоков. Это означает, что в любой момент данные только что удаленного файла будут перезаписаны ядром.
Итак, в двух словах, удаление файла любого размера равносильно удалению его inode из файловой системы в linux и других управляемых системах и займет то же время.
Это происходит из-за того, что sed обрабатывает построчно. вам нужно сделать такой цикл :sed -e ':again' -e 'N;s/\n/xxxxx/' -e 'tagain'
, или проще использоватьtr "\n" "xxxxx"
$ seq 10 | sed 'N;s/\n/+/'
1+2
3+4
5+6
7+8
9+10
N
добавляет следующую строку в пространство шаблонов, затем s
объединяет эти 2 строки с +
, а затем sed
печатает эту строку и повторяет сценарий для следующей строки ввода (, где строки 3 и 4 соединяются с +
... и т. д. ).
Вам понадобится
$ seq 10 | sed 'N;N;N;N;N;N;N;N;N;s/\n/+/g'
1+2+3+4+5+6+7+8+9+10
или используйте цикл в вашем скрипте sed, чтобы соединить все строки:
$ seq 10 | sed -e :1 -e '$!N;s/\n/+/;t1'
1+2+3+4+5+6+7+8+9+10
Обратите внимание, что он поглощает весь ввод в пространство шаблонов, что плохо масштабируется для больших файлов.
Чтобы соединить строки с одним разделителем символов, вы можете использоватьpaste
:
$ seq 10 | paste -sd + -
1+2+3+4+5+6+7+8+9+10
Для многосимвольного разделителя -без загрузки всего ввода в память:
$ seq 10 | awk -v sep=-+- -vORS= 'NR>1 {print sep}; 1; END {if (NR) print RS}'
1-+-2-+-3-+-4-+-5-+-6-+-7-+-8-+-9-+-10
Ваш sed
скрипт с аннотациями:
# Append the next line of input to the pattern space with an embedded newline
N
# Replace the embedded newline with the string xxxxxxxxx
s/\n/xxxxxxxxx/
# (implicit print, start next cycle, overwriting the pattern space with the next line)
Итак, вы читаете строку, добавляете строку, подставляете+выводите. Затем вы читаете третью строку, добавляете четвертую и заменяете + вывод.
Если вы хотите собрать все строки, вы можете сделать это двумя способами с помощью sed
.
Используйте явный цикл ::top; N; $!btop; s/\n/xxxxxxxxx/g
, то есть «добавьте следующую строку, и если мы еще не в конце, сделайте это снова, затем замените все новые строки».
Используйте пространство для хранения :1{h;d;}; H; ${x;s/\n/xxxxxxxxx/g;p;}; d
, то есть «скопируйте первую строку в пространство для хранения и удалите из ввода, добавьте туда же все остальные строки и удалите их из ввода, но при достижении последней строки поменяйте местами в пустом месте замените символы новой строки и распечатайте результат».
Основное различие между этими двумя альтернативами заключается в том, что первая никогда не выходит из первого цикла до самого конца и не создает строку в пространстве шаблонов, тогда как вторая выполняется до конца для каждой строки ввода и накапливает результат в пространство для удержания.
Другой способ взглянуть на это, используя awk
.
Ваш sed
код по существу
awk '{ line = $0; getline; print line "xxxxxxxxx" $0 }'
Вам нужно
awk '{ line = (line == "" ? $0 : line "xxxxxxxxx" $0 ) } END { print line }'
Это имитирует использование пространства удержания в sed
.
Или,
awk '{ line = $0; while (getline > 0) line = line "xxxxxxxxx" $0; print line }'
Это имитирует использование явного цикла в sed
.