wyświetla listę plików ponumerowanych w określonym zakresie

16

Mam zestaw plików w katalogu ponumerowanym w następujący sposób:

file1.txt
file2.txt
...
file30.txt
...

Teraz chciałbym uruchomić polecenie dla określonego zakresu plików, powiedzmy od 18 do 31.

Do tej pory korzystałem z następujących sposobów,

trzy argumenty

command file1[8-9].txt file2[0-9].txt file3[0-1].txt

Załóżmy teraz, że chcę co drugi numer,

pętla

for i in `jot - 18 31 2`; do echo file${i}.txt; done | xargs command

wydaje się, że jest to bardziej niezawodna pętla (spacje działają)

for i in `jot - 18 31 2`; do echo "\"file${i}.txt\" "; done | xargs command

ale wydaje się, że powinien istnieć prostszy sposób na zrobienie tego. Domyślam się, że najlepszym rozwiązaniem jest utworzenie funkcji bash, która zwróci zestaw plików do wiersza poleceń. Wtedy mógłbym zrobić coś takiego,

command `filerange file 18 31`

Czy istnieją lepsze sposoby lub sugestie dotyczące robienia tego skutecznie?

Z góry przepraszam, jeśli przegapiłem to samo pytanie, na które odpowiedziano gdzie indziej w Internecie lub w Internecie superuser.

mleczarz
źródło
Zaktualizowałem swoje pytanie, aby uwzględnić rozwiązanie za pomocą forpętli, która pozwala na spacje w nazwach plików za pomocą xargs. Wydaje się, że działa, jeśli nie masz bash 4. Jeśli masz bash 4, zdecydowanie użyj rozszerzenia nawiasów klamrowych! Zobacz wybraną odpowiedź. Bezwstydna wtyczka do aktualizacji Snow Leopard bash
milkypostman

Odpowiedzi:

25

Spróbuj tego:

for file in file{18..31}.txt

Jest znany jako „wyrażenie sekwencji” i jest częścią funkcji rozszerzenia nawiasu klamrowego Basha . Działa w Bash 3 i 4.

Funkcja przyrostu jest nowością w Bash 4. Prawdopodobnie masz Bash 3.x.

W Bash 4 możesz:

$ for i in {1..6..2}; do echo $i; done
1
3
5

Ale w Bash 3 musisz to zrobić, aby uzyskać te same wyniki:

$ for ((i=1; i<=6; i+=2)); do echo $i; done

Ta sama forma z przyrostem o jeden:

$ for ((i=1; i<=6; i++)); do echo $i; done

Każda z liczb może być zmienną lub wyrażeniem. Jednak w wyrażeniu sekwencyjnym liczby muszą być stałymi

Oto przykład użycia tego formularza w twoich plikach:

for ((i=18; i<=31; i++))
do
    echo "file${i}.txt"
done

Kolejną nową funkcją wyrażeń sekwencji w Bash 4 jest możliwość dołączania zer wiodących. Jest to przydatne, jeśli chcesz utworzyć (i użyć) pliki o numerach, które można odpowiednio posortować.

W Bash 4:

touch file{001..010}.txt

tworzyłby pliki o nazwach „file001.txt” do „file010.txt”. Ich nazwy będą sortowane w oczekiwanej kolejności. Bez wiodących zer „file10.txt” posortowałby przed „file1.txt”.

Aby pracować z plikami, możesz użyć tej samej wiodącej składni zerowej:

for file in file{001..010}.txt; do echo "$file"; done

W Bash 3, jeśli potrzebujesz zer wiodących, musisz samodzielnie wpisać wartość:

for i in {1..10}
do
    printf -v i '%03d' $i 
    echo "file${i}.txt"
done

printfInformacja będzie dołączana wartość i z zerem na początku a więc szerokość 3, na przykład ( „4” staje się „004”).

Edytować:

Dostosowanie spacji w nazwach plików jest proste:

$ touch "space name "{008..018..3}" more spaces"
$ ls -l sp*
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000008 more spaces
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000011 more spaces
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000014 more spaces
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000017 more spaces
$ for f in "space name "{008..018..3}" more spaces"; do mv "$f" "${f}.txt"; done
$ ls -l sp*
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000008 more spaces.txt
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000011 more spaces.txt
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000014 more spaces.txt
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000017 more spaces.txt
Wstrzymano do odwołania.
źródło
Dziękuję Ci! Nie wiem, gdzie to było całe moje życie. Jedną rzeczą, której nie mogę dostać do pracy, jest to, że przyrost nie wydaje się działać w wersji bash OSX. tzn. nie mogę zabrać się {1..10..2}do pracy w bash OSX.
milkypostman
To dlatego, że Snow Leopard (z jakiegoś powodu) używa bash 3.1. To jest problem z oprogramowaniem.
milkypostman
@milkypostman: Funkcja przyrostu i wiodące zera {01..10}są nowe w Bash 4. Prawdopodobnie masz Bash 3.x. Jeśli potrzebujesz funkcji zwiększania lub aby użyć zmiennych dla granic zakresu, skorzystaj z tego formularza: for ((i=1; i<=10; i+=2}(lub i++do zwiększenia o jeden). Każda z liczb może być zmienną lub wyrażeniem. Następnie, aby użyć wartości wewnątrz forpętli: echo "file${i}.txt". In Bash 3, if you need leading zeros, inside the for loop do: printf -vi '% 03d' $ i`, która poprzedzi wartość iz zerami wiodącymi, więc szerokość wynosi na przykład 3 (na przykład „4” staje się „004”).
Wstrzymano do odwołania.
Dennis, czy jest jakiś sposób, by zaktualizować swoje rozwiązanie, aby zawierało alternatywny formularz. Jako komentarz to trochę zaciemniające to, co prawdopodobnie powinienem dostać.
milkypostman
@milkypostman: Zobacz moją zredagowaną odpowiedź.
Wstrzymano do odwołania.