Я хотел бы удалить последний символ строки, я попробовал этот маленький скрипт:
#! /bin/sh
t="lkj"
t=${t:-2}
echo $t
но он печатает "lkj", что я делаю не так?
Я хотел бы удалить последний символ строки, я попробовал этот маленький скрипт:
#! /bin/sh
t="lkj"
t=${t:-2}
echo $t
но он печатает "lkj", что я делаю не так?
Ответы:
В оболочке POSIX синтаксис ${t:-2}означает что-то другое - он расширяется до значения tif t, установленного и отличного от NULL, а в противном случае до значения 2. Чтобы обрезать один символ с помощью раскрытия параметров, вы, вероятно, захотите следующий синтаксис:${t%?}
Обратите внимание , что в ksh93, bashили zsh, ${t:(-2)}или ${t: -2}(обратите внимание на пробел) являются законными как расширение подстроки , но, вероятно , не то , что вы хотите, так как они возвращают подстроки , начиная с позицией 2 символа в с конца (т.е. удаляет первый символ iиз строка ijk).
См. Раздел «Расширение параметров оболочки» Справочного руководства Bash для получения дополнительной информации:
${parameter%word}удаляет сопоставление с самым коротким суффиксным шаблоном word- см. раздел «Расширение параметров»man bash
С bash4.2 и выше, вы можете сделать:
${var::-1}
Пример:
$ a=123
$ echo "${a::-1}"
12
Обратите внимание, что для более старых версий bash(например, bash 3.2.5в OS X) вы должны оставлять пробелы между двоеточиями и после них:
${var: : -1}
bashверсии 4.2-alpha и выше, слишком плохая версия, к которой у меня есть доступ, более ранняя. : - /
${var:offset:lenght}была добавлена только в bash 4.2. Может быть, OSX добавить свой собственный патч для bash.
для удаления последних nсимволов из строки, которая не использует sedИЛИ awk:
> echo lkj | rev | cut -c (n+1)- | rev
так, например, вы можете удалить последний символ, one characterиспользуя это:
> echo lkj | rev | cut -c 2- | rev
> lk
с revmanpage:
ОПИСАНИЕ
Утилита rev копирует указанные файлы в стандартный вывод, меняя порядок символов в каждой строке. Если файлы не указаны, читается стандартный ввод.
ОБНОВИТЬ:
если вы не знаете длину строки, попробуйте:
$ x="lkj"
$ echo "${x%?}"
lk
С помощью sed это должно быть так же быстро, как
sed 's/.$//'
Ваше единственное эхо тогда echo ljk | sed 's/.$//'.
Используя это, строка из 1 строки может быть любого размера.
Несколько вариантов в зависимости от оболочки:
t=${t%?}t=`expr " $t" : ' \(.*\).'`t=${t[1,-2]}t=${t:0:-1}t=${t:0:${#t}-1}t=${t/%?}t=${t/~(E).$/}@ {t=$1} ~~ $t *?Обратите внимание, что хотя все должны удалять последний символ , вы обнаружите, что некоторые реализации (те, которые не поддерживают многобайтовые символы) вместо этого отбрасывают последний байт (так что, вероятно, испортил бы последний символ, если он был многобайтовым). ).
Предполагается, что exprвариант $tне заканчивается более чем одним символом новой строки. Он также вернет ненулевой статус выхода, если полученная строка окажется 0( 000или даже -0с некоторыми реализациями). Это также может дать неожиданные результаты, если строка содержит недопустимые символы.
t=${t%?}это не Bourne, но вы вряд ли встретите Bourne shell в наши дни. ${t%?}работает во всех других, хотя.
fishидет работа 2.3.0, которая представила stringвстроенную версию, не была выпущена во время Q & A. В версии, на которой я ее тестирую, вам нужны string replace -r '(?s).\z' '' -- $t(и я ожидаю, что они захотят это изменить, они должны изменить флаги, которые они передают в PCRE) или более замысловатые. Это также плохо работает с символами новой строки, и я знаю, что они планируют изменить это также.
Самый портативный и самый короткий ответ почти наверняка:
${t%?}
Это работает в bash, sh, ash, dash, busybox / ash, zsh, ksh и т. Д.
Он работает с использованием расширения параметров старой школы. В частности, %указывается, чтобы удалить наименьший соответствующий суффикс соответствия параметра, tкоторый соответствует шаблону глобуса ?(т. Е. Любому символу).
См. «Удалить самый маленький шаблон суффикса» здесь для более подробного объяснения и дополнительной информации. Также см. Документы для вашей оболочки (например:) в man bashразделе «Расширение параметров».
В качестве примечания: если вы хотите вместо этого удалить первый символ, вы должны использовать ${t#?}, так как #совпадения начинаются с начала строки (префикс), а не с конца (суффикс).
Также стоит отметить, что как %и , так и #иметь %%и ##версии, которые соответствуют самой длинной версии данного шаблона, а не самой короткой. Оба ${t%%?}и ${t##?}будут делать то же самое, что и их единственный оператор в этом случае (так что не добавляйте лишний лишний символ). Это потому, что данный ?шаблон соответствует только одному символу. Смешайте *с некоторыми не подстановочными знаками, и все становится более интересным с %%и ##.
Понимание расширений параметров или, по крайней мере, знание об их существовании и умение их искать, невероятно полезно для написания и расшифровки сценариев оболочки многих разновидностей. Расширения параметров часто выглядят как тайная оболочка вуду для многих людей, потому что ... ну ... они являются тайной оболочкой вуду (хотя довольно хорошо документированы, если вы знаете, что нужно искать "расширение параметров"). Определенно хорошо иметь в поясе инструментов, когда вы застряли в оболочке.
Вы также можете использовать, headчтобы распечатать все, кроме последнего символа.
$ s='i am a string'
$ news=$(echo -n $s | head -c -1)
$ echo $news
i am a strin
Но, к сожалению, некоторые версии headне включают ведущий -вариант. Это тот случай, headкоторый идет с OS X.
Просто для завершения некоторых возможных применений чистого Bash:
#!/bin/bash
# Testing substring removal
STR="Exemple string with trailing whitespace "
echo "'$STR'"
echo "Removed trailing whitespace: '${STR:0:${#STR}-1}'"
echo "Removed trailing whitespace: '${STR/%\ /}'"
Первый синтаксис берет подстроку из строки, синтаксис
Для второго, обратите внимание на знак, который означает «с конца строки», а синтаксис
${STRING:OFFSET:LENGTH} %
${STRING/PATTERN/SUBSTITUTION}
И вот две более короткие формы вышеупомянутого
echo "Removed trailing whitespace: '${STR::-1}'"
echo "Removed trailing whitespace: '${STR%\ }'"
Здесь снова обратите внимание на %знак, означающий «Удалить (т. Е. Заменить на») самый короткий совпавший шаблон (здесь представленный пробелом «\» от конца ПАРАМЕТРА - здесь с именем STR