Дистрибутив Linux состоит из многих частей. Всем частям, которые основаны на программном обеспечении, лицензируемом под GPL GNU и другими разрешенными для копирования лицензиями, нужно было выпустить источник кода. Например, если Вы поставляете что-то, основывался на ядре Linux, необходимо обеспечить источник ядра Linux, а также любой патч, который Вы сделали к источнику ядра (однако, для ядра Linux, Linus Torvalds интерпретирует GPL как не требующий для обеспечения исходного кода для кода, который только загружается как модуль). Можно поставить исходный код на CD или предложить тот, люди загружают его с веб-сайта или любого другого разумного метода.
Вы не должны обеспечивать исходный код для non-GPL программ, которые включены в ту же систему. Большинство дистрибутивов (Red Hat, SuSE, Ubuntu, даже Debian ¹) предоставляет некоторое небесплатное программное обеспечение в двоичной форме только.
Существуют другие варианты Unix, которые не только не требуют открытого лицензирования никакого базового компонента, но даже запрещают его. Конечно, оборот - то, что необходимо будет заплатить для лицензирования их. Они имеют тенденцию работать в большой области сервера, не во встроенной области: Солярис, AIX, HP-UX, SCO... IOS Apple работает на том, что иногда называют высокопроизводительной встроенной системой (MP3-плееры, мобильные телефоны), но они - исключительно аппаратные средства Apple, Вы не сможете лицензировать ОС.
Существуют также варианты Unix, лицензируемые в соответствии с лицензией BSD. Лицензия BSD позволяет Вам делать в значительной степени, что Вы хотите с ними только с условием, что Вы подтверждаете, что существует некоторое BSD-лицензированное программное обеспечение внутри (детали требования подтверждения зависят от версии лицензии). Существует несколько дистрибутивов Unix, где целая базовая система обеспечивается в соответствии с лицензией BSD: FreeBSD, OpenBSD, NetBSD являются основными. Обратите внимание, что некоторые компоненты имеют различные лицензии; в частности, компилятор C является GCC, который находится под GPL GNU (Вы, вероятно, не поставили бы компилятор однако).
Для встроенной системы MINIX, более вероятно, будет соответствующим. Это опубликовано в соответствии с лицензией BSD и разработано и для обучения и для встроенных систем.
Главное преимущество Linux состоит в том, что он имеет драйверы для примерно любой системы, которую можно найти. Дело обстоит не так с другими нельдами. Даже для MINIX, Вам придется, вероятно, записать набор драйверов.
В коммерческой встроенной системе значение не находится в самой операционной системе. Значение находится в интеграции всего аппаратного и программного компонента и создании применимого и надежного продукта из этих разрозненных частей. Настаивать на встроенной системе без бесплатных программных обеспечений, во многих случаях, только изобретает велосипед, но переосмысливает каждую часть механизма. Концентрат на части, где Вы увеличиваете стоимость, и повторное использование, что проверено на практике для остальных. Обеспечение исходного кода для компонентов GPLv2 имеет незначительную стоимость (ситуация немного более сложна для GPLv3, но мы добираемся широко вне темы).
¹ существует некоторый спор относительно того, является ли небесплатное программное обеспечение, что проект Debian предусматривает установку в системе Debian, частью распределения Debian или программного обеспечения, которое, оказывается, распределяется проектом Debian и упаковывается для установки в системах Debian. Это шарлатаны как утка, это идет как утка, и я не хочу быть перетащенным в спор относительно того, является ли это уткой.
Почему никто не дал очевидного ответа?
sed 's/.*\(...\)/\1/'
... или чуть менее очевидного
grep -o '...$'
Признаю, что второй имеет недостаток что строки с менее чем тремя символами исчезают; но вопрос явно не определял поведение в этом случае.
Если строка находится в переменной, вы можете сделать:
printf %s\\n "${var#"${var%???}"}"
, которая покладывает последние три символа из значения $ var
, как:
${var%???}
... а затем полоски от головы $ var
Все , но Что было только что уделить:
${var#"${var%???}"}
Этот метод имеет свои выделения и недостатки. На светлой стороне он полностью портативный POSIX и должен работать в любой современной оболочке. Кроме того, если $ var
не содержит не менее трех символов Ничего , но тянутся \ N
EWLINE. Опять же, если вы хотите , он напечатан в этом случае, вам нужен дополнительный шаг, как:
last3=${var#"${var%???}"}
printf %s\\n "${last3:-$var}"
таким образом $ Last3
, только когда-либо пустым, если $ var
Содержит 3 или меньше байтов. И $ var
когда-либо заменит только $ HAST3
, если $ Last3
пустой или unset
- и мы знаем, что это не unset
, потому что мы просто установили его.
Вы можете сделать это, но это немного ... чрезмерно:
for s in unlimited 987654 123456789; do
rev <<< $s | cut -c 1-3 | rev
done
ted
654
789
Использование awk
:
awk '{ print substr( $0, length($0) - 2, length($0) ) }' file
ted
654
789
Если ваш текст находится в переменную оболочки под названием String
, вы можете сделать это в Bash
, ZSH
или MKSH
Shell:
printf '%s\n' "${STRING:(-3)}"
или
printf '%s\n' "${STRING: -3}"
, которые также имеют преимущество для работы с KSH93, от которого приступает синтаксис.
Точка заключается в том, что :
должен быть отделен от -
, в противном случае он становится $ {var: -Default}
Оператор Борна оболочка.
Эквивалентный синтаксис в ZSH
или yash
оболочки:
printf '%s\n' "${STRING[-3,-1]}"
Нам не нужно регулярное выражение или более одного процесса только для подсчета символов.
Команда tail
, часто используемая для отображения последних строк файла, имеет параметр -c
( --bytes
), который кажется как раз подходящим инструментом для этого:
$ printf 123456789 | tail -c 3
789
(Когда вы находитесь в оболочке, имеет смысл использовать метод, подобный ответу mikeserv, потому что он экономит запуск процесса для хвоста
.)
Теперь вы запрашиваете последние три символа ; Это не то, что дает вам этот ответ: он выводит последние три байта !
Пока каждый символ состоит из одного байта, tail -c
просто работает. Таким образом, его можно использовать, если набор символов - ASCII
, ISO 8859-1
или вариант.
Если у вас есть ввод Unicode, например, в общем формате UTF-8
, результат неверен:
$ printf 123αβγ | tail -c 3
�γ
В этом примере, используя UTF-8
, греческие символы Альфа, бета и гамма состоят из двух байтов:
$ printf 123αβγ | wc -c
9
Параметр -m
может, по крайней мере, подсчитать реальные символы Юникода:
printf 123αβγ | wc -m
6
Хорошо, последние 6 байтов дадут нам последние 3 символа:
$ printf 123αβγ | tail -c 6
αβγ
Итак, tail
не поддерживает обработку общих символов и даже не пытается (см. Ниже): он обрабатывает строки переменного размера, но не символы переменного размера.
Скажем так: tail
как раз подходит для структуры задачи, которую нужно решить, но неверно для типа данных.
Если посмотреть дальше, выясняется, что это GNU coreutils, набор основных инструментов, таких как sed
, ls
, tail
и разрез
, еще не полностью интернационализирован. В основном это касается поддержки Unicode.
Например, cut
будет хорошим кандидатом для использования вместо хвоста здесь для поддержки персонажа; У него есть опции для работы с байтами или символами, -c
( - bytes
) и -m
( - chars
) ;
Только -m
/ - chars
, начиная с версии
вырезано (GNU coreutils) 8.21
, 2013,
{{1} }не реализованы!
Из вырезать информацию
:
`-c CHARACTER-LIST'
`--characters=CHARACTER-LIST'
Select for printing only the characters in positions listed in CHARACTER-LIST.
The same as `-b' for now, but internationalization will change that.
См. Также этот ответ с на Невозможно использовать `cut -c` (` --characters`) с UTF-8? .
Пуленепробиваемое решение для строк utf-8:
utf8_str=$'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82' # привет
last_three_chars=$(perl -CAO -e 'print substr($ARGV[0], -3)' "$utf8_str")
Или используйте:
last_three_chars=$(perl -MEncode -CO -e '
print substr(decode("UTF-8", $ARGV[0], Encode::FB_CROAK), -3)
' "$utf8_str")
для предотвращения неправильная обработка данных.
Пример:
perl -MEncode -CO -e '
print substr(decode("UTF-8", $ARGV[0], Encode::FB_CROAK), -3)
' $'\xd0\xd2\xc9\xd7\xc5\xd4' # koi8-r привет
Выводит примерно следующее:
utf8 "\xD0" does not map to Unicode at /usr/lib/x86_64-linux-gnu/perl/5.20/Encode.pm line 175.
Не зависит от настроек локали (т.е. работает с LC_ALL = C
). Bash
, sed
, grep
, awk
, rev
требуют что-то вроде этого: LC_ALL = en_US .UTF-8
Общее решение:
Вы можете определить кодировку с помощью uchardet . См. Также связанные проекты .
Вы можете декодировать / кодировать с помощью Encode в Perl, кодеков в Python 2.7
Пример :
Извлечь последние три символа из строки utf-16le и преобразовать эти символы в utf-8
utf16_le_str=$'\xff\xfe\x3f\x04\x40\x04\x38\x04\x32\x04\x35\x04\x42\x04' # привет
chardet <<<"$utf16_le_str" # outputs <stdin>: UTF-16LE with confidence 1.0
last_three_utf8_chars=$(perl -MEncode -e '
my $chars = decode("utf-16le", $ARGV[0]);
my $last_three_chars = substr($chars, -3);
my $bytes = encode("utf-8", $last_three_chars);
print $bytes;
' "$utf16_le_str"
)
См. также: perlunitut , Python 2 Unicode HOWTO
Получить размер строки с помощью:
size=${#STRING}
Затем получить подстроку из последних n символов:
echo ${STRING:size-n:size}
Например:
STRING=123456789
n=3
size=${#STRING}
echo ${STRING:size-n:size}
даст:
789
Как насчет использования «expr» или «rev»?
Ответ, аналогичный тому, который дал @ G-Man : expr "$ yourstring": '. * \ (. .. \) $ '
У него тот же недостаток, что и у решения grep.
Хорошо известный трюк - комбинировать «вырезать» с «оборотом»: echo «$ yourstring» | rev | cut -n 1-3 | rev
printf не будет работать, если в строке есть пробелы.
Код ниже для строки с пробелом
str="Welcome to Linux"
echo -n $str | tail -c 3
nux
хвост -n 1 ревизии.log | awk '{ print substr ($0, 0, length ($0 )-(length ($0 )-13 ))}'
Если вы хотите напечатать первые тринадцать символов с начала