GNU head
и tail
начиная с версии 8.25 для coreutils есть -z
опция для этого.
В старых версиях или для систем , отличных от GNU, вы можете попробовать и своп \0
и \n
:
find ... -print0 |
tr '\0\n' '\n\0' |
head |
tr '\0\n' '\n\0'
Обратите внимание, что некоторые head
реализации не могут справиться с NUL-символами (и это не требуется для POSIX), но там, где find поддерживает -print0
, head
и текстовые утилиты обычно поддерживают NUL-символы.
Вы также можете использовать функцию для переноса любой команды между двумя tr
s:
nul_terminated() {
tr '\0\n' '\n\0' | "$@" | tr '\0\n' '\n\0'
}
find ... -print0 | nul_terminated tail -n 12 | xargs -r0 ...
Имейте в виду, что под nul_terminated
, \0
подразумевается символ новой строки. Так, например, заменить \n
на _
:
find . -depth -name $'*\n*' -print0 | nul_terminated sed '
p;h;s,.*/,,;s/\x0/_/g;H;g;s,[^/]*\n,,' | xargs -r0n2 mv
( \x0
будучи также расширением GNU).
Если вам нужно выполнить более одной команды фильтрации , вы можете сделать:
find ... -print0 |
nul_terminated cmd1 |
nul_terminated cmd2 | xargs -r0 ...
Но это означает выполнение нескольких избыточных tr
команд. Кроме того, вы можете запустить:
find ... -print0 | nul_terminated eval 'cmd1 | cmd2' | xargs -r0 ...
\x0
вместо\n
разграничения значений? (¹ так что вы можете справиться со значениями, которые могут содержать\n
)