Bash удалить первые и последние символы из строки

100

У меня есть такая строка:

|abcdefg|

И я хочу получить новую строку, называемую каким-либо образом (например, string2) с исходной строкой без двух |символов в начале и в конце, чтобы у меня было следующее:

abcdefg

Это возможно в bash?

Маттео Пальяцци
источник

Ответы:

121

Ты можешь сделать

string="|abcdefg|"
string2=${string#"|"}
string2=${string2%"|"}
echo $string2

Или, если длина вашей строки постоянна, вы можете сделать

string="|abcdefg|"
string2=${string:1:7}
echo $string2

Кроме того, это должно работать

echo "|abcdefg|" | cut -d "|" -f 2

Также это

echo "|abcdefg|" | sed 's/^|\(.*\)|$/\1/'
Крис Харпер
источник
2
а такжеawk -F\| '{ print $2 }' <<<"|string|"
энзотиб
1
@enzotib У вас всегда есть крутые awkрешения. Мне нужно учиться awk.
Крис Харпер
3
а также IFS='|' read string2 <<< $string:)
организовать
10
а также в bash 4.2 и новее"${string:1:-1}"
гейра
Читайте в разделе «Расширение параметров» в man bash.
Немо
63

Вот решение, которое не зависит от длины строки (bash):

string="|abcdefg|"
echo "${string:1:${#string}-2}"
Samus_
источник
30

Если отбросить несколько постов, перечисленных здесь, кажется, что самый простой способ сделать это:

string="|abcdefg|"
echo ${string:1:-1}

редактировать: работает на Ubuntu с Bash 4.2; не работает на centOS с bash 4.1

jlunavtgrad
источник
21

Другой способ - использовать head& tailкоманды:

$ echo -n "|abcdefg|" | tail -c +2 | head -c -2
abcdefg
Zavior
источник
1
У меня была цепочка [something something]с целью сократить скобки, поэтому echo "[something something]" | tail -c +2 | head -c -2сработало. Спасибо за совет!
Айн Тохври
Очевидно, так и должно быть echo -n "|abcdefg|" | tail -c +2 | head -c -1. Я не уверен, почему мои изменения были отклонены ... Это очень грустно, если честно. Более man headподробная информация
Дмитрий Хамитов
10

И еще один:

string="|abcdefg|"
echo "${string//|/}"
Стивен Пенни
источник
9

Вы также можете использовать Sed для удаления | не просто ссылаться на сам символ, а использовать позиционные ссылки, как в:

$ echo "|abcdefg|" | sed 's:^.\(.*\).$:\1:'
abcdefg

Где ':' - разделители (вы можете заменить их на / или любой символ, отсутствующий в запросе, любой знак, следующий за символом s, сделает это) Здесь ^ (символ вставки) означает в начале строки ввода, а $ (доллар) означает в конце. . (точка), что это после каретки, а тот, что перед знаком доллара, представляет один символ. Другими словами, мы удаляем первый и последний символы. Имейте в виду, что это удалит любые символы, даже если | его нет в строке.

EX:

$ echo "abcdefg" | sed 's:^.\(.*\).$:\1:'
bcdef
Metafaniel
источник
3

функция оболочки

Немного более многословный подход, но он работает с любым видом первого и последнего символа, не обязательно должен быть одинаковым. Основная идея заключается в том, что мы берем переменную, читаем ее символ за символом и добавляем только те, которые хотим, к новой переменной

Вот вся эта идея, отформатированная в хорошую функцию

crop_string_ends() {
    STR="$1" 
    NEWSTR="" 
    COUNT=0 
    while read -n 1 CHAR 
    do
        COUNT=$(($COUNT+1)) 
        if [ $COUNT -eq 1 ] || [ $COUNT -eq ${#STR} ] 
        then
            continue 
        fi 
        NEWSTR="$NEWSTR"$CHAR 
    done <<<"$STR" 
    echo $NEWSTR 
}

И вот та же самая функция в действии:

$> crop_string_ends "|abcdefg|"                                                                                       
abcdefg
$> crop_string_ends "HelloWorld"                                                                                      
elloWorl

питон

>>> mystring="|abcdefg|"
>>> print(mystring[1:-1])
abcdefg

или в командной строке:

$ python -c 'import sys;print sys.stdin.read()[1:-2]' <<< "|abcdefg|"                                             
abcdefg

AWK

$ echo "|abcdefg|" | awk '{print substr($0,2,length($0)-2)}'                                                      
abcdefg

Рубин

$ ruby -ne 'print $_.split("|")[1]' <<< "|abcdefg|"                                                               
abcdefg
Сергей Колодяжный
источник
2

Небольшое и универсальное решение:

expr "|abcdef|" : '.\(.*\).'

Особый в этом случае и допускающий, что '|' персонаж может быть там или нет:

expr "|abcdef" : '|*\([^|]*\)|*'
Тоси До
источник
2
$ string="|abcdefg|"
$ string="${string#?}" && string="${string%%?}"
$ echo "$string"
abcdefg

С http://tldp.org/LDP/abs/html/parameter-substitution.html

${var#Pattern}
Удалить из $varпо кратчайшим частям , $Patternкоторая соответствует переднему концу с $var. Удалить из по длинной части , которая соответствует задней части из .
${var%%Pattern}
$var$Pattern$var

Брайан
источник