Відповіді:
По-перше, ви повинні бути чіткими щодо того, чого ви хочете. Якщо ви знаєте, що рядок закінчується, .rtfі ви хочете видалити .rtf, ви можете використовувати var2=${var%.rtf}. Якщо ви не знаєте, що таке суфікс, але ви хочете видалити все, починаючи з останнього ., тоді ви можете використовувати var2=${var%.*}. Якщо ви хочете лише тримати все до першого ., можете скористатися var2=${var%%.*}. Ці останні два варіанти мають однаковий результат, якщо існує лише один період, але якщо їх може бути більше, слід вирішити, який ви хочете.
Якщо ви дійсно хочете завжди видаляти точну кількість символів, ось кілька варіантів.
Ви конкретно вказали bash, тому ми почнемо з bash вбудованих. Той, хто працював довше, - це той самий синтаксис видалення суфіксу, який я використовував вище: для видалення чотирьох символів використовуйте var2=${var%????}. Вам потрібно один знак питання на кожний символ видалений, так що це стає непростим для більшої довжини підрядки.
Трохи новіше вилучення підрядка: var2=${var::${#var}-4}. Тут ви можете поставити будь-яке число замість, 4щоб видалити іншу кількість символів. (Значення ${#var}замінюється довжиною рядка, тому це насправді просить зберегти перші (довжина - 4) символи.)
Новіші версії bash (зокрема 4+, а це означає, що версія, що постачається з MacOS, не працюватиме) дозволять вам спростити це просто var2=${var::-4}.
Якщо ви фактично не використовуєте bash, а якусь іншу оболонку типу POSIX, вилучення суфіксів все одно буде працювати, навіть у звичайному старому тире (де ніхто з решти не буде). У Zsh, всі вони працюють , але ви повинні поставити 0між двокрапкою: і var2=${var:0:-4}т.д. В КШ, вам потрібно 0 , а також використовувати явне вираз довжиною 4: var2=${var:0:${#var}-4}.
Ви, звичайно, можете використовувати заміну команд, щоб зробити це за допомогою утиліти; Є багато, що буде працювати, але щось подібне var2=$(cut -c -4 <<<"$var")- це, мабуть, найкоротший варіант.
Ви можете зробити так:
#!/bin/bash
v="some string.rtf"
v2=${v::-4}
echo "$v --> $v2"
bash4+, але в більш ранній версії можна використовувати трохи довший ${v::${#v}-4}.
${v::-4}croaks "zsh: очікується закриття дужки". Але відповідь @fredtantini нижче ${v:0:-4}працює добре.
Щоб видалити чотири символи з кінця рядка, використовуйте ${var%????}.
Щоб видалити все після остаточного .використання ${var%.*}.
${var#????}.
Що для мене працювало:
echo "hello world" | rev | cut -c5- | rev
# hello w
Але я використовував його для обрізки рядків у файлі, тому це виглядає незручно. Справжнє використання було:
cat somefile | rev | cut -c5- | rev
cutВи отримуєте лише обрізки з початкового положення, що погано, якщо вам потрібні ряди змінної довжини. Таким чином, це рішення повертає ( rev) рядок і тепер ми відносимо його кінцеве положення, потім використовуємо, cutяк було сказано, і повертаємо (знову ж rev), повертаємо його до початкового порядку.
revобертає рядки, а не рядки. echo $SOME_VAR | rev | ...напевно, не буде вести себе так, як можна було б очікувати.
Використання змінної розширення / заміни підрядків :
$ {var /% Шаблон / Заміна}
Якщо суфікс var збігається з шаблоном, замініть Заміна на шаблон.
Отже, ви можете зробити:
~$ echo ${var/%????/}
some string
Крім того,
Якщо у вас завжди однакові 4 букви
~$ echo ${var/.rtf/}
some string
Якщо це завжди закінчується на .xyz:
~$ echo ${var%.*}
some string
Ви також можете використовувати довжину рядка:
~$ len=${#var}
~$ echo ${var::len-4}
some string
або просто echo ${var::-4}
len=${#var}; echo ${var::len-4}можна скоротити до echo ${var:0:-4}:-) EDIT: або як вказував @iyonizer, просто echo ${var::-4}...
Ви можете використовувати sed,
sed 's/.\{4\}$//' <<< "$var"
Приклад:
$ var="some string.rtf"
$ var1=$(sed 's/.\{4\}$//' <<< "$var")
$ echo $var1
some string
var2?
Я спробував наступне, і це спрацювало на мене:
#! /bin/bash
var="hello.c"
length=${#var}
endindex=$(expr $length - 4)
echo ${var:0:$endindex}
Вихід: hel
Сподіваємось, що наведений нижче приклад допоможе,
echo ${name:0:$((${#name}-10))} -> ${name:start:len}
start є початковою точкою рядкаlen - довжина струни, яку потрібно видалити.Приклад:
read -p "Enter:" name
echo ${name:0:$((${#name}-10))}
Вихід:
Enter:Siddharth Murugan
Siddhar
Примітка: Bash 4.2 додав підтримку негативної підрядки
У цьому випадку ви можете використовувати базове ім'я, якщо припустити, що у вас є той самий суфікс для файлів, які ви хочете видалити.
Приклад:
basename -s .rtf "some string.rtf"
Це поверне "деяку рядок"
Якщо ви не знаєте суфікс, і хочете, щоб він видалив усе після і, зокрема, останню крапку:
f=file.whateverthisis
basename "${f%.*}"
виводить "файл"
% означає рубати,. це те, що ти рубаєш, * це підстановка