ls 명령 색상을 find 또는 du의 출력과 병합하는 방법은 무엇입니까?

ls 명령 색상을 find 또는 du의 출력과 병합하는 방법은 무엇입니까?

cwd의 파일 및 폴더 크기를 나열하는 간단한 별칭이 있습니다.

(이 경우 도트 파일 포함, 크기 0 무시)

du -sh .[!.]* * | sort -hr | grep -v '^0'

이는 find를 통해서도 얻을 수 있습니다:

find .[!.]* * -maxdepth 0 -exec du -sh {} \; | sort -hr | grep -v '^0'

예제 출력:

// .ssh & .byobu are folders - .zsh* are files
// currently not able to distinguish them by type

... 
32K     .zshrc
25K     .ssh
20K     .zcompdump
19K     .byobu
...

ls 색상과 일치하는 출력의 파일/디렉토리 색상을 어떻게 지정할 수 있습니까?(LS_COLORS)

답변1

zsh스크립트는 $LS_COLORS. 모든 파일에 대해 호출 만 필요하므로 모든 파일을 stat호출하는 하단의 솔루션보다 훨씬 빠릅니다 ls. 그리고 공백이 있는 파일을 올바르게 처리합니다. ( \n또는 \t아직~ 아니다파일 이름에 허용됨)

그러나 구현이 완료되지 않았습니다. 파일 모드 문자열(예: lrwxrwxrwx심볼릭 링크의 경우)의 첫 번째 문자 또는 파일 확장자로 식별할 수 있는 다양한 파일 형식에 대한 색상만 포함했습니다. 즉, 누구나 쓸 수 있는 권한, suid 또는 고정 비트는 특별히 색상이 지정되지 않습니다. 이를 포함하는 것도 간단해야 합니다.

sourceduc다음을 수행하고 컬러 출력을 위해 새로운 쉘 함수를 사용하십시오 du.

zmodload -F zsh/stat b:zstat

function duc() {

  emulate zsh 
  setopt no_nomatch interactivecomments           # no_nomatch is necessary, to prevent error in "do .* *" if there are no dotfiles

  typeset -a aline
  typeset -A lscols
  local dircols acolor

  for i (${(s.:.)LS_COLORS}) {                    # split $LS_COLORS at ":"
    aline=(${(s:=:)i})                            # split every entry at "="
    lscols+=(${${aline[1]}/*.} ${aline[2]})       # load every entry into the associative array $lscols
  }

  duout=$(du -sh .* * 2> /dev/null | grep -v '^0' | sort -hr)
  for i (${(f)duout}) {                           # split output of "du" at newlines
    aline=(${(ps:\t:)i})                          # split every entry at \t
    zstat -s +mode -A atype ${aline[2]}           # determine mode (e.g. "drwx------") of file ${aline[2]}
    case ${${atype[1]}[1]} in                     # ${${atype[1]}[1]} is the first character of the file mode
      b)   acolor=$lscols[bd] ;;
      c|C) acolor=$lscols[cd] ;;
      d)   acolor=$lscols[di] ;;
      l)   acolor=$lscols[ln] ;;
      p)   acolor=$lscols[pi] ;;
      s)   acolor=$lscols[so] ;;
      -)   acolor=${lscols[${${aline[2]}:e}]};      # ${${aline[2]}:e} is the current file extention
           [[ -z $acolor ]] && acolor=$lscols[fi]   # unrecognized extention
           [[ -z $acolor ]] && acolor=00            # sometimes "fi" isn't set in $LS_COLORS, so fall back to normal color
           ;;
      *)   acolor=00 ;;
    esac
    print -n -- "${aline[1]}\t"        # print size (taken from du output)
    print -n "\\e[4${acolor}m"         # activate color
    print -n ${aline[2]}               # print file name
    print "\\e[0m"                     # deactivate color
  }
}

이것은 내 이전 스크립트이기도 합니다 zsh. 모든 파일에 대해 단일 ls명령이 실행되므로 불필요하게 복잡하고 속도가 매우 느릴 수 있습니다.

du_colored() {
  typeset -a duout
  duout=($(du -sh .* * | sort -hr | grep -v '^0'))
  for i ({1..$#duout..2}) {
    print -n "${duout[$i]}\t"
    ls -d --color ${duout[$(($i+1))]}
  }
}
  • 의지.*zsh~ 아니다.또는 일치 ..하지만 ..foo이와 유사한 파일은 누락됩니다..[!.]*
  • typeset -a배열을 선언합니다
  • for 루프는 배열에 대해 $i2단계로 1부터 값을 가져옵니다.

경고: 다음과 같은 파일이 있으면 심하게 깨질 수 있습니다.공백... 지금은 더 나은 생각이 없습니다.

답변2

이것이 내가 bash를 위해 생각해낸 것입니다. pv를 사용하여 출력 진행 상황을 표시합니다.

folder_size (){
  # read ls --color output into ls_colored_array 
  # thereby remove symlinks (@) and remove (/ and *) from folders and files

  ls -AF --color | grep -v @ | sed s'/[/\,*]$//'| xargs -n1 -L1 | read -d '\n' -r -a ls_colored_array

  # - loop over the array and issue du -sh for every element
  # - exchange du's ouput with ls's 
  # - run loop through pv with line option and
  #    size set to array-length showing progress
  # - finally sort the output using sort

  for i in "${ls_colored_array[@]}"; do
    echo -n "${i}" | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" | xargs -n1 -0 du -sh | awk -v i="$i" '{ printf "%-10s ", $1; $1=""; print i }'
  done | pv -pls"${#ls_colored_array[@]}" | sort -hr
}

이제 스크립트를 한 줄짜리로 바꿀 수 있습니다. 하지만 가장 큰 파일/폴더 10개 또는 폴더에만 플래그를 추가하여 기능을 개선하겠습니다.

답변3

이것은 나에게 효과적입니다.

#!/usr/bin/env bash

paste <(du --apparent-size --all --human-readable --max-depth=1 2>/dev/null |
    sed 's/\s.*//') \
    <(ls --color=always -1 --almost-all -U) | sort --human-numeric-sort

여기서 주요 명령은 이며 , 의 출력을 수평 으로 paste결합합니다 .lsdu

du각 줄은 다음과 같이 출력됩니다.

147291    ./.config

sed 's/\s.*//첫 번째 공백을 포함하여 이후의 모든 내용을 삭제합니다. 즉, ./.config나열된 항목 이름의 색상이 지정되지 않은 형식에는 관심이 없기 때문입니다. 여기서의 비결은 ls디렉토리의 내용을 동일한 방식으로 출력 하여 du각 항목을 해당 크기로 쉽게 결합할 수 있도록 하는 것입니다. -1(항목을 가로 대신 세로로 나열), -U(항목을 알파벳순 대신 처럼 디렉토리 순서로 나열 du) 및 --almost-all(숨겨진 디렉토리/파일도 나열하지만 제외 .하고 ..반대 --all) 의 도움으로 이를 수행할 수 있습니다. 그리고 물론 --color=always. 의 경우 du디렉토리 --all만 처리하는 것이 아니라 파일(숨겨진 파일 포함)과 디렉토리를 모두 처리하고 하위 디렉토리에서 작동을 --max-depth=1중지 하도록 하는 데 필요합니다( 's du와 마찬가지로 ).find-maxdepth 1

따라서 질문에 대답하려면 다음만 필요합니다.

paste <(du --all --max-depth=1 | sed 's/\s.*//') \
    <(ls --color=always -1 --almost-all -U)

다른 선택적 인수에 대해서는 다음과 같습니다.

  • --apparent-sizedu디스크 사용량보다 인쇄 크기가 뚜렷하게 나타납니다 (내 취향).
  • --human-readable사람이 읽을 수 있는 크기로 인쇄합니다.
  • 2>/dev/null제한된 디렉토리에서 permission denied실행을 시도한 경우 모든 오류를 필터링합니다 . 예:du/var
  • sort --human-numeric-sort크기를 내림차순으로 정렬 합니다 --human-numeric-sort.--human-readabledu

답변4

위의 답변 중 일부를 Mac의 oh-my-zshell과 결합하면 크기, 색상이 지정된 디렉터리 이름 및 정렬된 일반 텍스트 파일 이름이 제공되어 가장 큰 10개의 파일/디렉터리를 출력할 수 있습니다.

paste <(du -cks *) <(ls --color=always -1) | sort -nr | head | awk '{print $1 "  " $3}'

설명: 각 파일의
du디스크 사용을 위해 ; 디렉토리의 색상을 파악합니다. 위의 두 출력을 결합합니다. : 숫자 역 정렬; : 가장 큰 파일/디렉토리를 출력합니다. : 첫 번째 열(크기)과 세 번째 열(파일/색상화된 디렉터리 이름)만 출력합니다.-c:grand total -k: 1Kb blocks -s: entry
ls
paste
sort -nr
head
awk

관련 정보