Mam folderA
kilka plików z sekwencją numerów zaczynającą się od a_000000
. Chcę usunąć pliki zaczynające się od określonej liczby: powiedzmy a_000750
do końca plików w tym folderA
. Czy ktoś mógłby doradzić, jak to zrobić za pomocą skryptu powłoki?
16
rm a_000[89]* a_0007[5-9]*
?a_000[89]*
obejmuje każdy plik rozpoczynający się oda_0008
luba_0009
, ia_0007[5-9]*
obejmuje każdy plik rozpoczynający się od,a_0007
a następnie zawierający liczbę między 5 a 9, a po nim cokolwiek.Odpowiedzi:
Zakładając, że znasz lub możesz odgadnąć koniec zakresu, możesz użyć rozszerzeń nawiasów :
Powyższe spowoduje usunięcie 101 plików między a_000750 i a_000850 włącznie (i narzeka na nazwy plików, które odnoszą się do nieistniejących plików). Jeśli masz na to zbyt wiele plików, użyj
find
:Tutaj po
find
prostu wyświetla listę wszystkich pasujących plikówa_*
. Lista jest przekazywana dowhile
pętli, w której każda nazwa pliku jest wczytywana do zmiennej$file
. Następnie, używając funkcji manipulacji ciągiem bash , jeśli część numeryczna (znajdź drukuje pliki jako./file
, więc${file#./a_}
drukuje tylko liczbę) jest000750
większa lub większa, plik jest usuwany.-v
Jest właśnie tam, dzięki czemu można zobaczyć, jakie pliki zostały usunięte.Zauważ, że powyższe zakłada rozsądne nazwy plików. Jeśli twoje imiona mogą zawierać spacje, znaki nowej linii lub inne dziwne znaki, użyj tego:
źródło
[[
?[[
nie upraszcza tu[[ "${file#./a_}" > 000749 ]]
na przykład rzeczy , nie czyni go nawet krótszym. Nie lubię używać niepotrzebnej składni, a ta będzie działać nawet w prostszych powłokach, takich jakdash
.[[
lepiej radzi sobie ze spacjami i dziwnościami (nie dbam o to zbytnio>
).[
jest w porządku, jeśli cytujesz zmienną tak jak ja, działa na znacznie większej liczbie powłok i jest prostsza.Możesz zrobić coś takiego:
Lub:
Pierwsza metoda zakłada stały prefiks, usuwa go i sprawdza wartość.
Druga metoda zakłada sufiks o stałej długości (i wspólny stały prefiks) i opiera się na tym fakcie; i choć w leksykografii
201
jest wcześniej31
, to nie jest wcześniej031
.Sprawdź to za pomocą
echo
polecenia, a gdy będziesz już pewien, że zawiera listę poprawnych plików, użyjrm
zamiast tego.źródło
Rozwiązanie powłoki POSIX
Pierwsze rozwiązanie terdona opiera się na rozszerzaniu nawiasów klamrowych, które jest właściwością
bash
iksh
nie można go jednak używać w standardowej/bin/sh
powłoce, do której Ubuntu jest dowiązane symbolicznie/bin/dash
.W przypadkach, w których musisz polegać
/bin/sh
na przenośności swoich skryptów, istnieją dwa sposoby na rozwiązanie tego problemu. Jednym byłoby globbing. Właśniecd folderA
i stamtąd biegnijrm a_*
. Innym sposobem byłoby zaimplementowanie alternatywnego użycia pętli w stylu C.while <CONDITION>;do ...done
w języku powłoki i sformatowanie liczb za pomocąprintf
:Zauważ, że tutaj używam
echo
. wymienićecho "$filename"
zrm ./"$filename"
lubrm -- "$filename"
kiedy jesteś gotowy, aby usunąć pliki. Należy również pamiętać, że należy to zrobić, gdy jużcd
edytujesz żądany katalog.(ab) za pomocą awk
Awk, który jest przyjemnym językiem podobnym do C, może nam pomóc na dwa sposoby: (1) możemy wygenerować nazwy plików za pomocą pętli for i sformatować je za pomocą
sprintf
funkcji oraz (2) usunąć te pliki za pomocąsystem()
polecenia, które przekaże wygenerowaną nazwę pliku irm
polecenie do/bin/sh
:Perl
Kontynuując pomysł przenośnego podejścia, w którym „generujemy” nazwy plików, możemy zrobić to samo w Perlu:
źródło
Tak prosty jak
W twoim przykładzie to jest
źródło
a_00075
...