
GNU bash, версия 4.4.19(1)-релиз (x86_64-pc-linux-gnu)
Идея заключается в том, чтобы установить переменную в набор данных, разделенный NUL. Здесь$samples
Однако это приводит к:
предупреждение: подстановка команды: проигнорирован нулевой байт во входных данных
при выполнении:
samples="$(find . -type d -iregex './sample[0-9][0-9]' -printf "%f\0" | sort -z)"
Я подумал, что могу повторно использовать эту переменную, так как мне нужно повторять одни и те же значения несколько раз:
while IFS= read -rd '' sample; do
echo $sample
done<<< "$samples"
Я мог бы использовать \n
это \0
внаходитькоманда в этом конкретном случае, но хотелось бы знать, как, если это вообще возможно, сделать это с разделителем NUL.
По желанию я могу сделать:
while IFS= read -rd '' sample; do
echo $sample
done< <(find . -type d -iregex './E[0-9][0-9]' -printf "%f\0" | sort -z)
но - поскольку мне нужно выполнить цикл несколько раз, это приводит к очень избыточному коду - и мне пришлось бы запуститьнаходитьиСортироватькоманду каждый раз.
Может быть, преобразовать результат в массив?
- Это возможно?
- Почему данные, разделенные NUL, нельзя использовать как есть?
решение1
Фактом является то, что вы не можете хранить \0
нулевые байты в контексте строки bash из-за базовой реализации C. См.Почему $'\0' или $'\x0' - пустая строка? Должен быть нулевым символом, не так ли?.
Одним из вариантов было бы удаление нулевых байтов после команды сортировки в конце конвейера с использованием tr
и сохранением результата для решения немедленной проблемы выдаваемого предупреждающего сообщения. Но это все равно оставило бы вашу логику несовершенной, поскольку имена файлов с переводами строк все равно были бы сломаны.
Используйте массив, команду mapfile
or readarray
(в bash 4.4+) для непосредственного получения результатов из find
команды
IFS= readarray -t -d '' samples < <(find . -type d -iregex './sample[0-9][0-9]' -printf "%f\0" | sort -z)
решение2
Оболочка bash
не поддерживает то, что вы хотите сделать. zsh
Оболочка поддерживает из коробки.
% mkdir sample11 SAMple12 sample21 sample22 dir1
% ll
total 20
drwxrwxr-x 2 fpm fpm 4096 Jun 9 13:46 dir1
drwxrwxr-x 2 fpm fpm 4096 Jun 9 13:46 sample11
drwxrwxr-x 2 fpm fpm 4096 Jun 9 13:46 SAMple12
drwxrwxr-x 2 fpm fpm 4096 Jun 9 13:46 sample21
drwxrwxr-x 2 fpm fpm 4096 Jun 9 13:46 sample22
% samples=$(find . -type d -iregex './sample[0-9][0-9]' -print0 | sort -z)
% echo $samples
./sample11./SAMple12./sample21./sample22
% echo $samples | od -a
0000000 . / s a m p l e 1 1 nul . / S A M
0000020 p l e 1 2 nul . / s a m p l e 2 1
0000040 nul . / s a m p l e 2 2 nul nl
0000055
%