Я знаю, что cut
команда может печатать первые n
символы строки, но как выбрать последние n
символы?
Если у меня есть строка с переменным количеством символов, как я могу напечатать только последние три символа строки. например.
"неограниченный" вывод необходим "тэд" Требуется вывод «987654» «654» Требуется вывод «123456789» «789»
text-processing
cut
Одиссея
источник
источник
grep -o '.\{3\}$'
echo "unlimited" | python -c "print raw_input()[-3:]"
"echo unlimited" | java -jar EnterpriseWordTrimmer.jar
, но я не думаю, что действительно нужно вводить более тяжелый язык для манипулирования персонажами.java -server -Xms300M -Xmx3G -XX:+UseParallelGC -cp /path/to/all/the/jars/ -Dinput.interactive=false -Dinput.pipe=true -Dconfig.file=/path/to/config/last-three-letters.cfg -jar ...
grep -o -P '.{0,3}$'
напечатает последние 3 символа, даже если строка содержит менее 3 символов.-P
избегает необходимости избегать скобок.Сохраняя это простым - хвост
Нам не нужно регулярное выражение или более одного процесса только для подсчета символов.
Команда
tail
, часто используемая для отображения последних строк файла, имеет параметр-c
(--bytes
), который, кажется, является подходящим инструментом для этого:(Когда вы находитесь в оболочке, имеет смысл использовать метод, как в ответе mikeserv, потому что он экономит запуск процесса для
tail
.)Реальные символы Юникода?
Теперь вы просите последние три символа ; Это не то, что дает этот ответ: он выводит последние три байта !
Пока каждый символ - один байт,
tail -c
просто работает. Таким образом, он может быть использован, если набор символовASCII
,ISO 8859-1
или вариант.Если у вас есть ввод Unicode, как в обычном
UTF-8
формате, результат неправильный:В этом примере, используя
UTF-8
греческие символы альфа, бета и гамма длиной два байта:Опция
-m
может по крайней мере подсчитывать реальные символы Юникода:Итак, последние 6 байтов дадут нам последние 3 символа:
Таким образом,
tail
он не поддерживает обработку общих символов и даже не пытается (см. Ниже): он обрабатывает строки переменного размера, но не символы переменного размера.Скажем так:
tail
это правильно для структуры проблемы, которую нужно решить, но неправильно для вида данных.GNU coreutils
Глядя дальше, то получается, что Thee Coreutils GNU, совокупность основных инструментов , таких как
sed
,ls
,tail
иcut
, еще не в полной мере интернационализации. Что в основном о поддержке Unicode.Например,
cut
будет хорошим кандидатом для использования вместо хвоста здесь для поддержки символов; У него есть опции для работы с байтами или символами,-c
(--bytes
) и-m
(--chars
);Только что
-m
/--chars
есть в версииcut (GNU coreutils) 8.21
2013 года ,не реализован!
От
info cut
:См. Также этот ответ на Не можете использовать `cut -c` (` --characters`) с UTF-8? ,
источник
cut
похоже, не подходят .tail
должен иметь дело с байтами, а не символами. Однажды я сделал патч, чтобы добавить новую опцию, чтобы также выбирать персонажей, но я считаю, что никогда не сливался: - /tail -c3 -n10 /var/log/syslog
tail -c3 -n10 /var/log/syslog
запрашивает последние 10 строк, и это работает для меня. Вы используете вариант-c3
, а после этого конфликтующий вариант-n10
. Последний вариант имеет приоритет.Если текст в переменной оболочки называется
STRING
, вы можете сделать это вbash
,zsh
илиmksh
оболочки:Или
который также имеет преимущество для работы с ksh93, откуда исходит этот синтаксис.
Дело в том, что
:
он должен быть отделен от-
, в противном случае он становится${var:-default}
оператором оболочки Борна.Эквивалентный синтаксис в оболочке
zsh
илиyash
:источник
${STRING:(-3):3}
(указав поле длины ),${STRING: -3}
(с пробелом между:
и-
), или${STRING: -3:3}
.3
является несколько спорным, поскольку запрашивается «три символа от третьего до последнего символа включительно», что на практике является операцией, идентичной операции «Все символы начиная с третьего от последнего» включительно ".Использование
awk
:источник
Если строка находится в переменной, вы можете сделать:
Это лишает последние три символа значения
$var
like:... а затем снимает с головы
$var
все, кроме того, что было просто раздето:Этот метод имеет свои плюсы и минусы. С другой стороны, он полностью переносим POSIX и должен работать в любой современной оболочке. Кроме того, если
$var
не содержит по крайней мере три символа, ничего не\n
печатается, кроме конечной ewline. Опять же, если вы хотите, чтобы это было напечатано в этом случае, вам нужен дополнительный шаг, такой как:Таким образом,
$last3
он всегда пуст, только если$var
содержит 3 или менее байтов. И$var
только когда-либо заменяется,$last3
если$last3
пусто илиunset
- и мы знаем, что это неunset
потому, что мы просто установили его.источник
printf
строки формата?${VARNAME:(-3)}
(предполагаяbash
)?bash
как и в любой другой оболочке, требующей совместимости POSIX.csh
это не среди современных, POSIX-совместимых оболочек , которые я упоминаю здесь, к сожалению. Спецификация оболочки POSIX смоделирована послеksh
, которая смоделировала себя после комбинации обоихcsh
и традиционных оболочек в стиле Борна.ksh
объединяет в себеcsh
отличную функциональность управления заданиями и перенаправление ввода / вывода старого стиля Bourne. Он также добавил некоторые вещи - такие как концепции манипуляции со строками, которые я демонстрирую выше.csh
Насколько я знаю, это вряд ли сработает в любом традиционном , извините.Вы можете сделать это, но это немного ... чрезмерно
источник
Пуленепробиваемое решение для струн utf-8:
Или используйте:
предотвратить неправильную обработку данных.
Пример:
Выводит что-то вроде этого:
Не зависит от настроек локали (т.е. работает с
LC_ALL=C
).Bash
,sed
,grep
,awk
,rev
Требуется что - то вроде этого:LC_ALL=en_US.UTF-8
Общее решение:
Вы можете определить кодировку с помощью uchardet . Смотрите также связанные проекты .
Вы можете декодировать / кодировать с помощью Encode в Perl, кодеков в Python 2.7.
пример :
Извлеките последние три символа из строки utf-16le и преобразуйте эти символы в utf-8
Смотрите также: perlunitut , Python 2 Unicode HOWTO
источник
echo
ваш пуленепробиваемый источник?decode/encode
мой пуленепробиваемый источник. Вычистил мой ответ.LC_ALL=C
потому, что это очень «тупой» параметр, но он может сломаться, когда вы попытаетесь передать строку UTF-8 в SHIFT-5 или строку SHIFT-5 в KOI8 и т. Д.perl -CAO -e 'print substr($ARGV[0], -3)'
работает нормально.A
элементы @ARGV должны быть строками, закодированными в UTF-8,O
STDOUT будет в UTF-8.utf8_str
Как насчет использования "expr" или "rev"?
Ответ, аналогичный ответу @ G-Man : у
expr "$yourstring" : '.*\(...\)$'
него тот же недостаток, что и у решения grep.Хорошо известный трюк состоит в том, чтобы объединить «cut» с «rev»:
echo "$yourstring" | rev | cut -n 1-3 | rev
источник
rev
Решение выглядит как Glenn ДжекманаПолучить размер строки с помощью:
Затем получите подстроку последнего n символов:
Например:
даст:
источник
tail -n 1 revisions.log | awk '{print substr ($ 0, 0, длина ($ 0) - (длина ($ 0) -13))}'
Если вы хотите напечатать первые тринадцать символов с самого начала
источник
printf не будет работать, если в строке есть пробелы.
Ниже код для строки с пробелом
источник
printf
не работает, то вы делаете что-то очень неправильно.printf $str
(а неprintf "$str"
илиprintf '%s' "$str"
). И да,printf $str
это очень неправильно. (echo -n $str
не намного лучше.)