Насколько я знаю, все китайские символы 3 байта длиной при кодировании в UTF-8, нормальном кодировании Unicode на Unix. Но некитайские символы, такие как пробелы и новые строки могут быть другой шириной (основные управляющие символы, а также арабские формы цифры и другие, единственный широкий байт). split
утилита только понимает постоянные числа байтов, таким образом, она сократит без разбора неровно.
Необходимо будет использовать более сложный инструмент для разделения каждых 42 символов. Вот отрывок Perl, который должен добиться цели (непротестированный). Обратите внимание, что это - обработки каждый символ одинаково: китайские счетчики символов для 1, новая строка - также.
perl -CDS -e '
$n = 0;
while (read STDIN, $buf, 42) {
open OUT, sprintf("> output-$n.txt") or die;
print OUT $buf;
close OUT or die;
++$n;
}'
\
должен использоваться для предотвращения расширения $$
(идентификатор текущего процесса). Для тройной замены Вы должны удвоить оценку, так также больше Escape для предотвращения нежелательных расширений в каждой оценке:
#! /bin/bash
l0=value
l1=l0
l2=l1
l3=l2
l4=l3
echo $l0
eval echo \$$l1
eval eval echo \\$\$$l2
eval eval eval echo \\\\$\\$\$$l3
eval eval eval eval echo \\\\\\\\$\\\\$\\$\$$l4
Предположим, значение FOO
допустимое имя переменной (сказать BAR
), eval \$$FOO
разделяет значение BAR
в отдельные слова, рассматривает каждое слово как подстановочный шаблон и выполняет первое слово результата как команда, передавая другие слова как аргументы. Обратная косая черта перед долларом заставляет его рассматриваться буквально, таким образом, аргумент передал eval
встроенный четыре символьных строки $BAR
.
${${FOO}}
синтаксическая ошибка. Это не делает “двойной замены”, потому что нет такой функции ни в одной из общих оболочек (не с этим синтаксисом так или иначе). В zsh, ${${FOO}}
допустимо и двойная замена, но она ведет себя по-другому по сравнению с тем, что Вы хотели бы: это выполняет два последовательных преобразования на значении FOO
, оба из которых являются преобразованием идентификационных данных, таким образом, это - просто необычный способ записать ${FOO}
.
Если Вы хотите рассматривать значение переменной как переменная, остерегаются заключения в кавычки вещей правильно. Намного легче при установке результата на переменную:
eval "value=\${$FOO}"
Почему необходимо было бы сделать это?
Можно всегда делать это в несколько этапов как:
eval "l1=\${$var}"
eval "l2=\${$l1}"
...
Или используйте функцию как:
deref() {
if [ "$1" -le 0 ]; then
eval "$3=\$2"
else
eval "deref $(($1 - 1)) \"\${$2}\" \"\$3\""
fi
}
Затем:
$ a=b b=c c=d d=e e=blah
$ deref 3 a res; echo "$res"
d
$ deref 5 a res; echo "$res"
blah
FWIW, в zsh
:
$ echo ${(P)${(P)${(P)${(P)a}}}}
blah
Точно так же, как ${$foo}
не работает вместо ${(P)foo}
в zsh
, ни один не делает ${${$foo}}
. Просто необходимо указать каждый уровень абстракции:
$ foo=bar
$ bar=baz
$ baz=3
$ echo $foo
bar
$ echo ${(P)foo}
baz
$ echo ${(P)${(P)foo}}
3
Конечно, ${!${!foo}}
не работает в bash
, потому что bash
не позволяет вложенные замены.
zsh
устанавливается намного чаще, чем Вы могли бы принять. Это не может быть связано с sh
как bash
часто (но не всегда), но это может все еще быть доступно для сценариев оболочки. Думайте это как Вы делает Perl или Python.
– chepner
24.03.2013, 18:24
Не заморачиваясь цитированием, вы можете использовать эту функцию для многих уровней косвенности, например:
$ a=b
$ b=c
$ c=d
$ echo $(var_expand $(var_expand $a)
d
Или если у вас больше (!?! )уровней косвенности, которые вы могли бы использовать в цикле.
Предупреждает при подаче:
# Expand the variable named by $1 into its value. Works in both {ba,z}sh
# eg: a=HOME $(var_expand $a) == /home/me
function var_expand {
if [ "$#" -ne 1 ] || [ -z "${1-}" ]; then
printf 'var_expand: expected one argument\n' >&2;
return 1;
fi
eval printf '%s' "\"\${$1?}\""
}
{ba,z}sh
раствор Вот функция, которая работает в обоих {ba,z}sh
. Я считаю, что он также совместим с POSIX.
Не заморачиваясь с цитированием, вы можете использовать его для многих уровней косвенности, например:
$ a=b
$ b=c
$ c=d
$ echo $(var_expand $(var_expand $a)
d
Или если у вас больше (!?! )уровней косвенности вы можете использовать цикл.
Предупреждает при подаче:
# Expand the variable named by $1 into its value. Works in both {ba,z}sh
# eg: a=HOME $(var_expand $a) == /home/me
var_expand() {
if [ -z "${1-}" ] || [ $# -ne 1 ]; then
printf 'var_expand: expected one argument\n' >&2;
return 1;
fi
eval printf '%s' "\"\${$1?}\""
}
l3=l2; eval eval eval echo \\\$\\$\$$l3
→53294
так не точно модульный. – Profpatsch 15.03.2013, 13:29eval $(eval echo \$$l2)
? Я ненавижу удар, он не имеет абсолютно никакого смысла. – Profpatsch 15.03.2013, 13:31echo `eval echo \\$$VAR`
---------121 А-ч--------122650----, это - n ². Я даже не хочу пытаться добраться, почему это похоже на это. – Profpatsch 15.03.2013, 13:43