Załóżmy, że mam kilka plików o tej nazwie:
file01.txt file02.txt file03.txt ... file20.txt
i chcę wykonać polecenie w zakresie tych plików.
Wiem, jeśli chcę „rm” z „file05.txt” do „file09.txt”, mogę:
rm file0[5-9].txt
ale jak mogę „zapisać” zakres od pliku08.txt do pliku13.txt? Próbowałem tego kodu
rm file[08-13].txt
i to nie działa. Mógłbym uruchomić to polecenie:
rm file0[89].txt file1[0-3].txt
ale chciałbym wiedzieć, czy mogę to zrobić za pomocą tylko jednego dopracowanego argumentu na „rm”, jeśli jest to możliwe.
Odpowiedzi:
Musisz użyć rozszerzenia nawiasów
bash
:Spowoduje to usunięcie plików
file08
dofile13
, pojawi się komunikat o błędzie, jeśli brakuje pliku.Ustaw zakres w zależności od potrzeb.
Problem z operatorem globowania
[]
polega na tym, że traktuje on każdy znak / cyfrę w nim jako pojedynczy token, a zatem obsługuje tylko deklarację zakresu przy użyciu pojedynczych cyfr.Jeśli nalegasz na użycie
[]
, możesz użyć tego raczej brzydkiego wzoru, aby dopasowaćfile08
dofile13
:źródło
mv foo.{txt,md}
lubcp foo.txt{,.bak}
Niektóre powłoki, takie jak domyślna wersja Ubuntu
/bin/sh
(która jestdash
) lubmksh
nie mają rozwinięcia nawiasu, lub w przypadkuksh
- rozszerzenia nawiasu nie mogą używać zerowanych spacji:W takich przypadkach możemy skorzystać z
printf
formatowania część numer pliku i użyć pętli while wdrożyć c podobny do zachowania pętli (notatka zastąpićecho
zrm
lub cokolwiek chcesz):I to jest dość przenośny - działa z
dash
,ksh
,mksh
, równieżbash
. W przypadkuksh
ibash
możemy również użyćc-style for loop syntax (but not in case of
mkshor
dash`):Zauważ, że w takim
bash
przypadkuprintf
obsługuje drukowanie do zmiennej, a zatem moglibyśmy to zrobićprintf -v num "%.2d" "$i"
zamiast korzystać z zastępowania poleceń.źródło