Jak „rm” lub „mv” szereg plików, takich jak file01.txt, file02.txt… file85.txt

23

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.


źródło
Odpowiedzi na prawie identyczne pytanie tutaj: stackoverflow.com/questions/25049411/...
arielf

Odpowiedzi:

38

Musisz użyć rozszerzenia nawiasów bash:

rm file{08..13}.txt

Spowoduje to usunięcie plików file08do file13, 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ć file08do file13:

rm file0[8-9].txt file1[0-3].txt
heemayl
źródło
5
rozwijanie nawiasów klamrowych jest również przydatne w przypadku przecinków, takich jak for mv foo.{txt,md}lubcp foo.txt{,.bak}
Kos
2

Niektóre powłoki, takie jak domyślna wersja Ubuntu /bin/sh(która jest dash) lub mkshnie mają rozwinięcia nawiasu, lub w przypadku ksh- rozszerzenia nawiasu nie mogą używać zerowanych spacji:

$ ksh -c 'echo {05..13}'
5 6 7 8 9 10 11 12 13

W takich przypadkach możemy skorzystać z printfformatowania część numer pliku i użyć pętli while wdrożyć c podobny do zachowania pętli (notatka zastąpić echoz rmlub cokolwiek chcesz):

$ i=5; while [ "$i" -le 10 ]; do num=$(printf "%.2d" "$i" ); echo "file$num.txt";i=$(($i+1)); done
file05.txt
file06.txt
file07.txt
file08.txt
file09.txt
file10.txt

I to jest dość przenośny - działa z dash, ksh, mksh, również bash. W przypadku kshi bashmożemy również użyć c-style for loop syntax (but not in case ofmksh ordash`):

$ ksh -c 'for((i=5;i<11;i++)); do num=$(printf "%.2d" "$i" ); echo "file$num.txt";done'             
file05.txt
file06.txt
file07.txt
file08.txt
file09.txt
file10.txt

Zauważ, że w takim bashprzypadku printfobsługuje drukowanie do zmiennej, a zatem moglibyśmy to zrobić printf -v num "%.2d" "$i"zamiast korzystać z zastępowania poleceń.

Sergiy Kolodyazhnyy
źródło