bash에서 문자열을 숫자로 정렬하는 방법은 무엇입니까?


37

디렉토리에이 파일들이 있다면

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

문자열의 숫자 부분을 기준으로 오름차순으로 표시되도록 Bash에 어떻게 나열 할 수 있습니까? 따라서 결과 순서는입니다 cwcch1.pdf, cwcch2.pdf, ..., cwcch9.pdf, cwcch10.pdf.

내가 궁극적으로하려고하는 것은 PDF와 pdftk다음을 연결하는 것입니다.

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

그러나 정렬이 잘못되어 작동하지 않습니다.


이에 대한 모든 훌륭한 답변에 감사드립니다. 유닉스와 마찬가지로이 고양이를 피부에 바르는 데는 여러 가지 훌륭한 방법이 있습니다.
ngm

답변:


7

약간 다른 접근법이 필요하지만 이와 같은 것이 원하는 것을 할 수 있습니다.

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

아하, 좋은 접근! 그것은 실제로 내가 무엇을하는지 감사합니다.
ngm

62

당신 sort은 당신 을 위해 이것을 할 수 있습니다 :

sort --version-sort

정렬 매뉴얼 페이지에서 관련 항목 발췌 : -V, --version-sort natural sort of (version) numbers within text
panmari

이것이 당신이 필요로하는 것입니다. :하지만 당신의 종류가이 옵션을 제공하지 않은 경우이 게시물을 살펴 걸릴 stackoverflow.com/a/4495368/1240018
eventhorizon

30

이 특정 예제의 경우 다음을 수행 할 수도 있습니다.

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

즉, 필드 구분 기호 (-th)로 'h'를 사용하여 두 번째 필드 (-k2)에서 숫자 (-n)를 정렬합니다.


하나의 필드에서 분리 한 후 정렬하는 것이 좋습니다. 이는 앞으로 유용 할 것입니다. 감사합니다.
ngm

6

-vGNU에서이 옵션을 사용할 수 있습니다 ls: 텍스트 내 자연 정렬 (버전) 숫자.

ls -1v cwcch*

옵션이 다른 의미를 갖는 BSD ls(예 : OS X)에서는 작동하지 않습니다 -v.


이것은 가장 간단한 해결책이며, 더 많은 지지자들이 필요합니다!
davidparks21

2

명령 행에서 직접 쉘 확장을 사용하십시오. 확장은 제대로 주문해야합니다. pdftk의 명령 줄 구문을 올바르게 이해 하면 원하는 작업을 수행합니다.

# 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

또는 다른 접근 방식을 시도 할 수 있습니다. 이런 식으로해야 할 때는 보통 미리 숫자를 올바르게 형식화하려고합니다. 늦게 들어 와서 PDF가 이미 귀하의 예와 같이 번호가 매겨지면이 번호를 사용하여 번호를 다시 매길 것입니다.

# 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

이제 표준 ls정렬이 제대로 작동합니다.


2
아마도 좀 더 간결하게 :pdftk cwcch{{1..9},{10..18}}.pdf ...
추후 공지가있을 때까지 일시 중지되었습니다.

좋은 팁은 표준 Bourne 쉘 확장 구문 bash입니까 , 아니면 확장입니까?
quack quixote

2

다음은 sort를 사용하는 방법입니다.

ls | sort -k1.6n

0

Sort -g 는 숫자를 오름차순으로 정렬하는 데 사용됩니다.

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


다음 하나의 라이너는 PDF 파일 이름으로 파일을 반복하고 egrep -o 로만 숫자를 가져 오고 sort -g 를 사용 하여 숫자를 오름차순으로 정렬합니다 . 그런 다음이 숫자를 sed에 공급하고 연결합니다. 그런 다음 uniq으로 중복 출력을 제거합니다.


uniq 대신 awk를 사용할 수도 있습니다.

awk '!x[$0]++'

위의 내용은 uniq와 같습니다.


당신이 찾고있는 것은 하나의 라이너입니다.

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


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 

편집하다:

명령 출력 :

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

하나의 라이너가 tmp파일에서 작동 합니까 ? 답변에 붙여 넣을 출력이 있습니까?
Xen2050

예. 편집 섹션의 OP에 출력을 포함 시켰습니다.
Aguevara
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.