Почему эта команда работает только для каждой другой линии?

Удаление файла, в свою очередь, приводит к выполнению системного вызова vfs_unlink, а затем fs-специфического fs_unlink. Именно эти вызовы добираются до родительского каталога и удаляют inode соответствующего файла, в результате чего его дентри становится отрицательным. Данные на диске (какого бы размера они ни были) остаются как есть, с единственным изменением: блок, в котором они находятся, перемещается в банк свободных блоков. Это означает, что в любой момент данные только что удаленного файла будут перезаписаны ядром.

Итак, в двух словах, удаление файла любого размера равносильно удалению его inode из файловой системы в linux и других управляемых системах и займет то же время.

-1
10.08.2018, 17:59
3 ответа

Это происходит из-за того, что sed обрабатывает построчно. вам нужно сделать такой цикл :sed -e ':again' -e 'N;s/\n/xxxxx/' -e 'tagain', или проще использоватьtr "\n" "xxxxx"

0
28.01.2020, 05:06
$ 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
3
28.01.2020, 05:06

Ваш 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.

  1. Используйте явный цикл ::top; N; $!btop; s/\n/xxxxxxxxx/g, то есть «добавьте следующую строку, и если мы еще не в конце, сделайте это снова, затем замените все новые строки».

  2. Используйте пространство для хранения :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.

2
28.01.2020, 05:06

Теги

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