W bash, jak sortować ciągi znaków z liczbami?


37

Jeśli mam te pliki w katalogu

cwcch10.pdf
cwcch11.pdf
cwcch12.pdf
cwcch13.pdf
cwcch14.pdf
cwcch15.pdf
cwcch16.pdf
cwcch17.pdf
cwcch18.pdf
cwcch1.pdf
cwcch2.pdf
cwcch3.pdf
cwcch4.pdf
cwcch5.pdf
cwcch6.pdf
cwcch7.pdf
cwcch8.pdf
cwcch9.pdf

jak mogę wyświetlić je w Bash, aby były w porządku rosnącym numerycznie w oparciu o część liczbową ciągu? Tak więc wynikowa kolejność jest cwcch1.pdf, cwcch2.pdf, ..., cwcch9.pdf, cwcch10.pdfitd.

To, co ostatecznie próbuję zrobić, to połączyć pliki PDF pdftkz czymś takim, jak poniżej

pdftk `ls *.pdf | sort -n` cat output output.pdf

ale to nie działa, ponieważ moje sortowanie jest nieprawidłowe.


Dzięki za wszystkie świetne odpowiedzi na to. Jak zawsze w przypadku Uniksa, istnieje wiele różnych doskonałych sposobów na skórowanie tego kota.
ngm

Odpowiedzi:


7

Coś takiego może zrobić to, co chcesz, choć ma nieco inne podejście:

pdftk $(for n in {1..18}; do echo cwcch$n.pdf; done) cat output output.pdf

Aha, fajne podejście! Rzeczywiście robi to, co ja, dzięki.
ngm


30

W tym konkretnym przykładzie możesz również to zrobić:

ls *.pdf | sort -k2 -th -n

Oznacza to, że sortuj numerycznie (-n) na drugim polu (-k2), używając „h” jako separatora pól (-th).


Dzielenie, a następnie sortowanie według jednego pola - to świetna wskazówka, która na pewno przyda się w przyszłości, dzięki.
ngm

6

Możesz użyć -vopcji w GNU ls: naturalny rodzaj (wersji) liczb w tekście.

ls -1v cwcch*

Nie działa to z BSD ls(np. W OS X), gdzie -vopcja ma inne znaczenie.


To najprostsze rozwiązanie, potrzebuje więcej pozytywnych opinii!
davidparks21

2

Użyj rozszerzenia powłoki bezpośrednio w wierszu polecenia. Rozszerzenie powinno porządkować je poprawnie. Jeśli dobrze rozumiem pdftkskładnię wiersza poleceń, zrobi to, co chcesz:

# shell expansion with square brackets
pdftk cwcch[1-9].pdf cwcch1[0-9].pdf cat output output.pdf

# shell expansion with curly braces
pdftk cwcch{{1..9},{10..18}}.pdf cat output output.pdf

Lub możesz spróbować innego podejścia. Kiedy muszę zrobić coś takiego, zwykle staram się odpowiednio sformatować swoje liczby przed czasem. Jeśli się spóźnię, a pliki PDF są już ponumerowane jak twój przykład, użyję tego do zmiany numeracji:

# rename is rename.pl aka prename -- perl rename script
# this adds a leading zero to single-digit numbers
rename 's/(\d)/0$1/' cwcch[1-9].pdf

Teraz standardowe lssortowanie będzie działać poprawnie.


2
Być może nieco bardziej zwięźle:pdftk cwcch{{1..9},{10..18}}.pdf ...
Wstrzymano do odwołania.

dobra wskazówka, dodane. czy to standardowa składnia rozszerzenia powłoki Bourne'a czy bashrozszerzenie?
quack quixote


0

Sortuj -g służy do sortowania liczb w porządku rosnącym.

anthony@mtt3:~$ sort --help | egrep "\-g"
-g, --general-numeric-sort  compare according to general numerical value


Poniższa linijka iteruje plik z nazwami plików PDF i pobiera liczby tylko za pomocą egrep -o i używa sort -g do sortowania liczb w porządku rosnącym . Następnie podaje te liczby do sed i podłącza je. Następnie usuwa dane wyjściowe duplikatów z uniq.


Zamiast uniq możesz także użyć awk:

awk '!x[$0]++'

Powyższe jest równoważne z uniq.


To, czego szukasz, to jedna wkładka:

for i in `cat tmp | egrep -o "[0-9]*" | sort -g`; do cat tmp | sed "s/\(^[a-z]*\)\([0-9]*\)\(\.pdf\)/\1$i\3/g" | uniq; done


Zawartość tmp:

anthony@mtt3:~$ cat tmp
cwcch10.pdf
cwcch11.pdf
cwcch12.pdf
cwcch13.pdf
cwcch14.pdf
cwcch15.pdf
cwcch16.pdf
cwcch17.pdf
cwcch18.pdf
cwcch1.pdf
cwcch2.pdf
cwcch3.pdf
cwcch4.pdf
cwcch5.pdf
cwcch6.pdf
cwcch7.pdf
cwcch8.pdf
cwcch9.pdf 

EDYTOWAĆ:

Wyjście polecenia:

anthony@mtt3:~$ for i in `cat tmp | egrep -o "[0-9]*" | sort -g`; do cat tmp | sed "s/\(^[a-z]*\)\([0-9]*\)\(\.pdf\)/\1$i\3/g" | uniq; done

cwcch1.pdf
cwcch2.pdf
cwcch3.pdf
cwcch4.pdf
cwcch5.pdf
cwcch6.pdf
cwcch7.pdf
cwcch8.pdf
cwcch9.pdf
cwcch10.pdf
cwcch11.pdf
cwcch12.pdf
cwcch13.pdf
cwcch14.pdf
cwcch15.pdf
cwcch16.pdf
cwcch17.pdf
cwcch18.pdf

Czy ten jeden liner działa na tmppliku? Jakieś dane wyjściowe do wklejenia w odpowiedzi?
Xen2050,

Tak. Uwzględniłem wyniki w moim OP w sekcji edycji.
Aguevara,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.