Bash видаляє перші та останні символи з рядка


98

У мене є такий рядок:

|abcdefg|

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

abcdefg

Це можливо в баш?

Відповіді:


120

Ви можете зробити

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|"
enzotib

1
@enzotib У вас завжди є круті awkрішення. Мені потрібно вчитися awk.
Кріс Харпер

3
а також IFS='|' read string2 <<< $string:)
влаштовуйте

10
а також, у "${string:1:-1}"
басі

Прочитайте в розділі "Розширення параметра" в man bash.
Немо

62

Ось рішення, яке не залежить від довжини рядка (bash):

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

29

Виходячи з кількох перелічених тут публікацій, здається, найпростіший спосіб це зробити:

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

редагувати: працює на ubuntu з bash 4.2; не працює на centOS з bash 4.1


19

Інший спосіб - використання head& tailкоманд:

$ echo -n "|abcdefg|" | tail -c +2 | head -c -2
abcdefg

1
У мене був рядок [something something]з метою вирізати дужки, так що echo "[something something]" | tail -c +2 | head -c -2вийшло. Дякую за пораду!
Ain Tohvri

Очевидно, так і має бути echo -n "|abcdefg|" | tail -c +2 | head -c -1. Я не впевнений, чому мене відхилили правки ... Чесно кажучи. Дивіться man headдля отримання додаткової інформації
Дмитро Хамітов


9

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

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

Де ':' є роздільниками (ви можете замінити їх на / або будь-який символ, який не знаходиться у запиті; будь-який знак, що відповідає s, це зробить) Тут ^ (caret) означає на початку рядка введення, а $ (долар) означає в кінці. The. (пункт), що це після карети і того, що це перед знаком долара, являє собою єдиний символ. Отже іншими словами ми видаляємо перший та останній символи. Пам'ятайте, що це видалить будь-які символи, навіть якщо | його немає в рядку.

EX:

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.