Jak mogę odwoływać się do ciągu według indeksu w sh / bash? To znaczy w zasadzie dzielenie.
Próbuję usunąć 5 znaków z nazwy pliku. Wszystkie nazwy mają strukturę: nazwa_kod_nr. Usiłuję usunąć 5-bitowy kod kodu. name_nr_
ma zawsze 10 znaków.
Czy istnieje coś takiego;
for i in * ; do mv "$i" "$i"[:10] ; done
bash
tag, jeśli pytasz osh
rozwiązanie?Odpowiedzi:
Proste jak to.
(grzmotnąć)
Voila
I wyjaśnienie z Advanced Bash-Scripting Guide ( rozdział 10. Manipulowanie zmiennymi ) , (z dodatkowymi NOTEwstawkami w celu podkreślenia błędów w tym podręczniku):
NOTEbrakujące cudzysłowy wokół rozszerzeń parametrów!
echo
nie powinien być wykorzystywany do dowolnych danych.NOTE:
expr substr
jest rozszerzeniem GNU.NOTE: Jest
echo
to zbędne i czyni go jeszcze mniej niezawodnym. Zastosowanieexpr substr + "$string1" 1 2
.NOTE:
expr
powróci z niezerowym statusem wyjścia, jeśli wyjście ma wartość 0 (lub -0, 00 ...).BTW. Książka jest obecna w oficjalnym repozytorium Ubuntu jako
abs-guide
.źródło
${var:1}
nie zwraca wartościvar
z „1. pozycji”, ale w rzeczywistości z 2. pozycji.W POSIX
sh
,"${var%?????}"
jest$var
pozbawiony ostatnich 5 znaków końcowych (lub$var
jeśli$var
zawiera mniej niż 5 znaków)"${var%"${var#??????????}"}"
to pierwsze 10 znaków$var
."${var%_*}"
jest$var
usuwany z najkrótszego ciągu pasującego_*
na końcu$var
(foo_bar_baz
->foo_bar
)."${var%%_*}"
: takie same, ale najdłuższe dopasowanie zamiast najkrótszego dopasowania (foo_bar_baz
->foo
).foo_bar_
:"${var%"${var##*_}"}"
(${var##pattern}
jest taki sam jak${var%%pattern}
szukanie wzoru na początku$var
zamiast na końcu).Z
zsh
:$var[1,-6]
za pierwszą postać na 6. miejscu od końca (czyli wszystkie oprócz ostatnich 5).$var[1,10]
dla pierwszych 10 znaków.Z
ksh
,bash
lubzsh
:"${var:0:10}"
: pierwsze 10 znaków$var
Z
bash
lubzsh
:"${var:0:-5}"
: wszystkie oprócz ostatnich 5 znaków (daje błąd i wychodzi ze skryptu, jeśli$var
jest ustawiony, ale zawiera mniej niż 5 znaków, również gdy$var
nie jest ustawiony za pomocązsh
).Jeśli potrzebujesz
sh
zgodności z Bourne , bardzo trudno to zrobić niezawodnie. Jeśli możesz zagwarantować, że wynik nie skończy się na znakach nowej linii, możesz:Będziesz także mieć limit długości
$var
(w zależności od systemu).We wszystkich tych rozwiązaniach, jeśli
$var
zawiera bajty, które nie mogą stanowić części prawidłowych znaków, YMMV.źródło
sh
nie zapewnia wbudowanego sposobu wyciągania podciągu z łańcucha (o ile widzę), ale zbash
tobą możesz zrobićTo da ci pierwsze dziesięć znaków wartości zmiennej
i
.Ogólny format to
${variable:offset:length}
.źródło
Większość powłok obsługuje pewne rozszerzenia parametrów, które mogą ci pomóc. W bash możesz użyć
W
dash
, przesunięcia nie są obsługiwane, ale można użyć wzorców wiodących i końcowych:źródło
Po pierwsze, nie używaj
for
pętli do nazw plików.Zatem coś takiego powinno pomóc.
źródło
for
nazw plików jest złe ?printf
aby być bezpieczniejszym. ... iread -r
.for
Pętla OP była w porządku, z wyjątkiem może brakujących--
. Widzę co najmniej 10 błędów w 4 liniach kodu! z których wiele znanych złych praktyk, takich jak zakładanie, że nazwy plików są jednowierszowe, używają echa, brakujących cytatów