ls -alt를 readlink와 결합

ls -alt를 readlink와 결합

나는 많은 심볼릭 링크와 거대한 하위 디렉토리가 있는 디렉토리를 가지고 있습니다. 상위 디렉토리에 있는 파일의 자세한 목록(시간순으로 정렬)을 얻고 싶지만 파일이 심볼릭 링크인 경우 링크를 대상으로 바꾸십시오.

이 명령은 readlink -f * | sort | uniq심볼릭 링크를 처리합니다. 그래서 당신은 생각할 것입니다

ls -alt `readlink -f * | sort | uniq`

단순히 명령 출력을 시간별로 정렬합니다 readlink. 하지만 상위 디렉터리의 콘텐츠뿐만 아니라 모든 하위 디렉터리의 콘텐츠도 반환됩니다. 원하는 출력(예: 시간별로 정렬된 목록)을 얻는 방법오직상위 디렉토리에 파일을 저장하고 링크를 대상으로 바꾸시겠습니까? 어떤 조언이라도 감사드립니다.

답변1

zshGNU를 사용하면 ls:

files=(*(NDoN:P))
(($#files)) && ls -ltd -- ${(u)files}

또는 간결성을 위해 익명 함수를 사용하십시오.

(){ (($#)) && ls -ltd -- ${(u)@}; } *(NDoN:P)

N활성화하고 nullglob, D dotglob숨겨진 파일을 포함하고, mtime 기준 정렬을 건너뛰고 oN, GNU와 동일한 작업을 수행합니다. 매개변수 확장 플래그는 배열에서 중복 항목을 제거합니다.ls:Preadlink -f(u)

또는 현재 디렉토리에 파일이 너무 많으면 위의 작업이 실패합니다.너무 많이 논쟁하다오류가 발생했습니다. zsh목록을 정렬하고 전달하면 ls -U(자체 정렬을 비활성화하려면 GNU 또는 호환 버전이 필요함 ) ls필요한 경우 목록을 더 작은 청크로 분할 zargs할 수 있습니다.xargs

autoload zargs
files=(*(ND-om:P))
zargs -r --eof= -- ${(u)files} '' ls -lUd --

심볼릭 -om링크는 해결 후 수정 시간을 기준으로 정렬됩니다.

(현재 차단은 해결에서 무한 루프가 있는 심볼릭 링크에서 zsh발생합니다 .):P

GNU 도구를 사용하면 bash다음을 수행할 수 있습니다.

shopt -s nullglob dotglob
files=(*)
((${#files[@]})) &&
  printf '%s\0' "${files[@]}" | # prints as NUL-delimited records
  xargs -r0 readlink -zf -- |   # get absolute canonical path
  LC_ALL=C sort -zu |           # removes duplicates
  xargs -r0 stat --printf '%.9Y/%n\0' -- | # get mtime with max precision
  sort -rnz |                   # sort numerically in reverse
  cut -zd/ -f2- |               # remove timestamp added earlier
  xargs -r0 ls -lUd --          # pass to as many ls invocations as needed

파일 목록이 충분히 작은 경우 다음과 같이 단순화할 수 있습니다.

shopt -s nullglob dotglob
files=(*)
((${#files[@]})) &&
  readlink -zf -- "${files[@]}" | # get absolute canonical path
  LC_ALL=C sort -zu |             # removes duplicates
  xargs -r0 ls -ltd --            # pass to ls

NUL로 구분된 레코드로 도구 간에 파일 목록을 항상 전달할 수 있는 방법을 알아보세요. NUL은 파일 경로에 나타날 수 없는 유일한 문자(및 바이트 값)이므로 유일하게 안전한 접근 방식입니다.

에서는 readlink -f * | sort줄바꿈으로 구분된 레코드로 파일 목록을 전달하므로 줄바꿈 readlinksort포함된 파일 이름이 손상됩니다. 또한 --이전에 나온 이름을 잊어버렸기 때문에 . *로 시작하는 파일 이름이 끊어집니다.-

에서는 상황이 훨씬 더 나쁩니다 ls -alt `cmd`. 이번에는 출력이 cmd공백, 탭 및 줄 바꿈(기본값으로 가정 $IFS)으로 분할되고 파일 이름 생성이 결과 단어에 대해 수행되므로 더 많은 문자가 차단됩니다. 그렇지 않은 경우 에도 나열됩니다 -d.ls콘텐츠이는 디렉토리 자체뿐만 아니라 인수로 전달된 디렉토리의 일부입니다.

답변2

다음 접근 방식을 고려해보세요.

ls | xargs realpath
ls $PWD | xargs realpath

다음 없이도 작동하는 이유를 여기에서 확인하세요 -1.https://unix.stackexchange.com/a/410557/537347

관련 정보