Odpowiedzi:
Po pierwsze, powinieneś wyraźnie powiedzieć, czego chcesz. Jeśli wiesz, że ciąg się kończy .rtf
i chcesz usunąć .rtf
, możesz użyć var2=${var%.rtf}
. Jeśli nie wiesz, co to jest przyrostek, ale chcesz usunąć wszystko, zaczynając od ostatniego .
, możesz użyć var2=${var%.*}
. Jeśli chcesz zachować wszystko na pierwszym miejscu .
, możesz użyć var2=${var%%.*}
. Te dwie ostatnie opcje mają ten sam wynik, jeśli jest tylko jeden okres, ale jeśli może być więcej niż jeden, powinieneś zdecydować, który chcesz.
Jeśli naprawdę chcesz zawsze usuwać dokładną liczbę znaków, oto kilka opcji.
Podałeś konkretnie bash, więc zaczniemy od wbudowanych bash. Najdłużej działała ta sama składnia usuwania sufiksów, której użyłem powyżej: aby usunąć cztery znaki, użyj var2=${var%????}
. Musisz usunąć jeden znak zapytania na znak, więc staje się nieporęczny w przypadku większych długości podciągu.
Nieco nowszy jest podciąg ekstrakcji: var2=${var::${#var}-4}
. Tutaj możesz wstawić dowolną liczbę zamiast, 4
aby usunąć inną liczbę znaków. (Symbol ${#var}
zastępowany jest długością łańcucha, więc w rzeczywistości prosi o zachowanie pierwszych (długości - 4) znaków).
Nowsze wersje bash (szczególnie 4+, co oznacza, że ta dostarczana z MacOS nie będzie działać) pozwalają to uprościć var2=${var::-4}
.
Jeśli tak naprawdę nie używasz bash, ale jakiejś innej powłoki typu POSIX, usuwanie sufiksu będzie nadal działać, nawet w zwykłym starym myślniku (gdzie żadna reszta nie będzie). W zsh, że wszystkie prace, ale trzeba umieścić 0
między dwukropkiem: var2=${var:0:-4}
itd. W ksh, potrzebny jest 0, a także mieć możliwość korzystania z wyraźnej długości 4 wyrażenie: var2=${var:0:${#var}-4}
.
Możesz oczywiście użyć zastępowania poleceń, aby to zrobić za pomocą programu narzędziowego; jest wiele, które będą działać, ale coś takiego var2=$(cut -c -4 <<<"$var")
jest prawdopodobnie najkrótszą opcją.
Możesz to zrobić w następujący sposób:
#!/bin/bash
v="some string.rtf"
v2=${v::-4}
echo "$v --> $v2"
bash
4+, ale we wcześniejszej wersji możesz użyć nieco dłuższego ${v::${#v}-4}
.
${v::-4}
wykrzykiwa „zsh: oczekiwany nawias zamykający”. Ale poniższa odpowiedź @fredtantini ${v:0:-4}
działa dobrze.
Aby usunąć cztery znaki z końca ciągu, użyj ${var%????}
.
Aby usunąć wszystko po ostatnim .
użyciu ${var%.*}
.
${var#????}
.
Dla mnie zadziałało:
echo "hello world" | rev | cut -c5- | rev
# hello w
Ale użyłem go do przycięcia linii w pliku, dlatego wygląda to niezręcznie. Rzeczywistym zastosowaniem było:
cat somefile | rev | cut -c5- | rev
cut
prowadzi cię tylko do przycinania z pewnej pozycji początkowej, co jest złe, jeśli potrzebujesz rzędów o zmiennej długości. To rozwiązanie odwraca ( rev
) ciąg znaków i teraz odnosimy się do jego końcowej pozycji, a następnie używa, cut
jak wspomniano, i odwraca (ponownie rev
) do pierwotnej kolejności.
rev
odwraca wiersze, a nie ciągi znaków. echo $SOME_VAR | rev | ...
prawdopodobnie nie zachowa się tak, jak można by się spodziewać.
Korzystanie ze zmiennego rozszerzenia / zamiany podciągów :
$ {var /% Pattern / Replacement}
Jeśli sufiks var pasuje do Wzorca, zamień Zastąp na Wzorzec.
Możesz więc zrobić:
~$ echo ${var/%????/}
some string
Alternatywnie,
Jeśli masz zawsze te same 4 litery
~$ echo ${var/.rtf/}
some string
Jeśli zawsze kończy się na .xyz
:
~$ echo ${var%.*}
some string
Możesz także użyć długości ciągu:
~$ len=${#var}
~$ echo ${var::len-4}
some string
lub po prostu echo ${var::-4}
len=${#var}; echo ${var::len-4}
można skrócić do echo ${var:0:-4}
:-) EDYCJA: lub jak zauważył @iyonizer, po prostu echo ${var::-4}
...
Możesz użyć sed,
sed 's/.\{4\}$//' <<< "$var"
Przykład:
$ var="some string.rtf"
$ var1=$(sed 's/.\{4\}$//' <<< "$var")
$ echo $var1
some string
var2
?
Wypróbowałem następujące i zadziałało to dla mnie:
#! /bin/bash
var="hello.c"
length=${#var}
endindex=$(expr $length - 4)
echo ${var:0:$endindex}
Wynik: hel
Mam nadzieję, że poniższy przykład pomoże,
echo ${name:0:$((${#name}-10))}
-> ${name:start:len}
start
jest punktem początkowym łańcuchalen
to długość ciągu, który należy usunąć.Przykład:
read -p "Enter:" name
echo ${name:0:$((${#name}-10))}
Wynik:
Enter:Siddharth Murugan
Siddhar
Uwaga: Bash 4.2 dodał obsługę ujemnego podłańcucha
W takim przypadku możesz użyć basename przy założeniu, że masz taki sam przyrostek na plikach, które chcesz usunąć.
Przykład:
basename -s .rtf "some string.rtf"
Zwróci to „jakiś ciąg”
Jeśli nie znasz przyrostka i chcesz usunąć wszystko po ostatniej kropce włącznie:
f=file.whateverthisis
basename "${f%.*}"
wypisuje „plik”
% oznacza chop,. to, co siekasz, * to symbol wieloznaczny