사람이 읽을 수있는 크기를 정렬하는 방법


11

기본적으로 파일을 찾은 다음 크기별로 정렬합니다. 사람이 읽을 수있는 크기로 정렬하지 않으면 스크립트가 작동합니다. 그러나 크기를 사람이 읽을 수 있기를 원합니다. 사람이 읽을 수있는 크기를 어떻게 정렬 할 수 있습니까?

예를 들면 다음과 같습니다.

 ls -l | sort -k 5 -n | awk '{print $9 " " $5}'

예상대로 작동합니다. 파일 크기가 오름차순으로 표시됩니다.

1.txt 1
test.txt 3
bash.sh* 573
DocGeneration.txt 1131
andres_stuff.txt 1465
Branches.xlsx 15087
foo 23735
bar 60566
2016_stuff.pdf 996850

이제 크기를 사람이 읽을 수 있기를 원하므로 ls에 -h 매개 변수를 추가했으며 이제 일부 파일이 잘못되었습니다.

 ls -lh | sort -k 5 -n | awk '{print $9 " " $5}'
1.txt 1
DocGeneration.txt 1.2K
andres_stuff.txt 1.5K
test.txt 3
Branches.xlsx 15K
foo 24K
bar 60K
bash.sh* 573
2016_stuff.pdf 974K


-k 5— 어떻게 작동합니까?
ctrl-alt-delor 2016 년

@ ctrl-alt-delor : 크기가 ls출력 의 5 번째 열에 있다고 생각합니다
jesse_b

2
du대신에 사용 ls하는 것이 좋습니다.
xenoid 2016 년

... 또는 find-printf그것과 %p%s(크기의 "인간화"뒤에) 포맷터.
Stephen Kitt 2016 년

@Jesse_b 내 오류, 방금 질문의 데이터 (이것이 내가 얻은 것으로 표시됨)가 정렬 된 입력이라고 가정했습니다.
ctrl-alt-delor

답변:


28

시험 sort -h k2

-h,-인간-숫자-소트-인간 판독 가능 숫자 비교 (예 : 2K 1G)

gnu sort, BSD sort 등의 일부입니다.


5
출력을 구문 분석 ls하지 않아야합니까?

3
@Tomasz 항상 그런 것은 아닙니다. 필요한 출력을 제공하는 경우 다른 포맷 작업으로 파이프하는 것은 특별히 위험하지 않습니다. 하지 말아야 할 것은 의 출력을 반복ls 하고 대신 파일 globbing을 사용하는 것입니다. 글 로빙만으로는 작동하지 않습니다. 즉, 아마도 du이것을 선호 할 것입니다 .
Bloodgain

1
@Bloodgain ls 형식은 시스템 / ls 바이너리에서 동일하다고 보장하지 않으므로 이식 가능하게 구문 분석하는 것은 불가능한 것으로 간주됩니다.
D. Ben Knoble

1
또한 공백이있는 파일 이름은
엉망

1
@Bloodgain : files=(); for f in *; do [[ -L "$f" ]] && files+=("$f"); done; echo ${#files[@]}(나는 symlink 테스트 스위치가 잘못되었을 수 있습니다). 심볼릭 링크를 신경 쓰지 않으면 배열 files=(*); echo ${#files[@]}을 사용 set하지 않고 사용하면 이식 가능합니다 .
D. 벤 Knoble

29

ls이 기능이 내장되어 있으면 -S옵션을 사용하고 역순으로 정렬하십시오.ls -lShr

       -r, --reverse
              reverse order while sorting

       -S     sort by file size, largest first

1
-h아닌 표준 ls옵션 , 영업 이익이 이미있는 경우 사용할 수 있어야합니다. 나머지는 표준이며 확실히 내가 작성한 답변입니다.
Toby Speight 2016 년

5
+1의 결과를 파싱하는 것을 망설이지 마십시오 ls.
David Richerby 2016 년

이것이 가장 좋은 대답이지만 @Toby의 의견에 정보를 포함해야 -S합니다 ls. FWIW -S는 Emacs의 라이브러리에서도 지원 ls-lisp.el되며 OS가없는 경우에 사용됩니다 ls. 예를 들어 MS Windows의 Emacs에서 작동합니다.
Drew

이것이 정답입니다.
산란

1
@Drew : Toby의 의견에 따르면 -h보편적으로 사용할 수는 없지만 OP는 이미 사용하고 있습니다. Toby가 제공하는 POSIX 링크에 있기 때문에 -S실제로 사용할 수 있어야 합니다. 그러나 POSIX 이외의 툴킷이 많이 있습니다.
Kevin

5

특정 쉘이 언급되지 않았으므로 zsh다음 은 쉘 에서 모든 작업을 수행하는 방법입니다 .

ls -lhf **/*(.Lk-1024oL)

**처럼 글로브 패턴은 일치 *하지만에 걸쳐 /같은 즉, 경로 이름에서 재귀 검색 할 것입니다.

ls명령을 사용하면 사람이 읽을 수있는 크기를 사용할 수 -h있고 긴 목록 출력 형식을 사용할 수 -l있습니다. 이 -f옵션은 정렬을 비활성화하므로 ls파일을 주어진 순서대로 나열합니다.

이 순서는 **/*(.Lk-1024oL)파일 이름 글 로빙 패턴으로 정렬 되므로 작은 파일이 먼저 나열됩니다. **/*비트는이 디렉토리 아래에있는 모든 파일 및 디렉토리와 일치하지만 (...)수정합니다 글로브의 행동 (그것이 "글로브 규정 자"이다).

그것은을의 oL끝에서 그 주문 ( o파일 크기에 의해) 이름 ( L"길이").

.시작시는 글로브는 일반 파일 (아무 디렉토리)와 일치한다.

Lk-1024크기가 1024 미만 KB ( "KB 길이 이하가 1024")는 비트 선택 파일.

zsh기본 대화식 쉘이 아닌 경우 다음을 사용할 수 있습니다.

zsh -c 'ls -lf **/*(.Lk-1024oL)'

숨겨진 이름과도 일치 setopt GLOB_DOTS시키 zsh -o GLOB_DOTS -c ...려면 (또는 )를 사용하십시오 . ... 또는 Dglob 한정자 문자열에 추가하십시오 .


경로 이름과 사람이 읽을 수있는 크기의 2 열 출력을 원한다고 가정하고 numfmtGNU coreutils를 사용 한다고 가정하면

zmodload -F zsh/stat b:zstat

for pathname in **/*(.Lk-1024oL); do
    printf '%s\t%s\n' "$pathname" "$(zstat +size "$pathname" | numfmt --to=iec)"
done

또는 더 빨리

paste <( printf '%s\n' **/*(.Lk-1024oL) ) \
      <( zstat -N +size **/*(.Lk-1024oL) | numfmt --to=iec )

4

귀하의 경우 sort이없는 -h옵션을 사용하면 다음과 같은 awk 명령 (매우 긴 불구하고)을 사용할 수 :

find . -type f -size -1024k -exec ls -al {} \; | sort -k 5 -n | awk '{if ($5 > 1099511627776) {print $9,$5/1024/1024/1024/1024"T"} else if ($5 > 1073741824) {print $9,$5/1024/1024/1024"G"} else if ($5 > 1048576) {print $9,$5/1024/1024"M"} else if ($5 > 1024) {print $9,$5/1024"K"} else {print $9,$5"B"}}' | column -t

그러면 출력이 바이트 단위로 정렬 된 다음 나중에 사람이 읽을 수있는 크기로 변환됩니다.


-1

이게 효과가 있을까요?

ls -l | awk '{if ($5<=1024) {print}}' | sort -k 5 -n | awk '{print $9"\t"substr($5/1024,1,3)"k"} '| column -t

첫 번째 awkexp는 1M보다 작은 파일을 찾고 두 번째 exp는 결과에서 바이트 크기를 가져 와서이를 KB로 변환하고 처음 3 개의 요소를 인쇄하여 사람이 읽을 수있는 크기를 제공합니다.


그것은 실제로 OPs 질문을 해결하지 못합니다. 현재 디렉토리에서만보고 일반 파일 만 인쇄합니다. 또한 1MB 대신 1Kb와 비교합니다. 마지막으로 우리는 왜 코드가 작동하는지에 대한 설명을 들었습니다.
grochmal 2016 년

내 나쁜 일이 추가되었습니다.
Vignesh SP
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.