find -exec ls의 출력 정렬


14

find … -exec ls -ls ;파일 이름 으로 정렬 된 결과를 알파 학적으로 출력 할 수 있습니까?

이것은 내 cron 명령입니다.

find /home/setefgge/public_html -type f -ctime -1 -exec ls -ls {} \;

이 명령은 대부분 정상적으로 작동합니다. 그러나 결과는 의미있는 순서로 정렬되지 않습니다. 파일 이름 필드를 기준으로 정렬하면 매우 유용합니다.


1
zsh를 사용하십니까? ls -ls **/*(.)
Kevin

@Kevin 확실하지 않다 – ls정렬 할 것이다.
Gilles 'SO- 악한 중지'

답변:


14

파일 이름에 줄 바꿈이 포함되어 있지 않다고 가정합니다.

find /home/setefgge/public_html -type f -ctime -1 -exec ls -nls {} + | sort -k 10

+대신 작업 ;을 종료하기 위해를 사용 -exec하면 호출을 일괄 처리하여 작업을 더 빠르게 수행 할 수 ls있습니다. sort명령을 통해 파이핑하여 정렬 할 수 있습니다 . 10 번째 필드에서 정렬을 시작하도록 지시하십시오 (처음 9 개는 메타 데이터 : 블록, 권한, 링크 수, 사용자, 그룹, 크기 및 3 개의 날짜 / 시간 필드). 이 옵션 -nls사용자 및 그룹에 숫자 값을 사용하도록 지시 하므로 공백이 포함 된 사용자 또는 그룹 이름의 위험을 피할 수 있습니다.

또는 zsh를 사용하면 glob 한정자 를 사용 하여 파일을 수집 및 정렬 하고 명령 줄이 너무 길면 여러 번 zargs실행 하여 어떤 이름도 가정하지 않아도 ls됩니다. 정렬을 피하기 위해 GNU ls(특히 -f옵션) 가 필요 합니다 ls(또 다른 접근법은 lszsh 's 에뮬레이션 하는 것입니다 zstat).

autoload -U zargs
zargs -- /home/setefgge/public_html/**/*(.c-2) -- ls -lnsf

정말 고맙습니다! 보낸 첫 번째 명령을 사용하여 정렬합니다. 더 짧은 경로를 사용하면 숫자가 여전히 10입니까? 예를 들어 public_html 대신 / home / setefgge에서 동일한 명령을 실행하면?
MaJ

@MaJ 10은 건너 뛴 필드 수이며 파일 이름의 크기와 관련이 없습니다.
Gilles 'SO- 악한 중지'

감사합니다. 귀하의 도움과 다른 사람들이 제공 한 도움에 감사드립니다. 이 문제가 해결되었다고 생각합니다. 내 cron 명령은 이제 파일을 정렬합니다. 내가 Stackexchange에 질문을 제출 한 것은 이번이 처음입니다. "해결됨"옵션이 표시되지 않습니다. 해결 된대로 게시하는 방법을 아는 사람이 있다면 계속 진행하십시오. 감사!
MaJ

@MaJ 문제를 해결 된 것으로 표시해야 할 가장 가까운 것은 답변 중 하나를 수락 된 것으로 표시하는 것입니다. 당신은 오직 당신 만이 그렇게 할 수 있습니다. 이렇게하려면 가장 도움이되는 답변 옆에있는 확인 표시를 클릭하십시오. 답변을 수락하면 평판 점수 2 점을 더 얻은 후 게시물을 투표 할 수 있습니다. 도움이되는 모든 게시물을 공감할 수 있습니다. 자세한 내용은 둘러보기 페이지누군가가 귀하의 질문에 답변 할 때도움말 페이지를 참조하십시오 .
Gilles 'SO- 악의를 멈춰라'

1

찾기 통해 결과를 정렬 한 다음 각 줄에 대해 ls를 실행 해보십시오.

find . -type f -ctime -1 | sort | while IFS= read -r filename; do ls -ls "$filename"; done

1

POSIX는 ls -long 목록의 날짜에 대해 다음과 같이 말합니다 .

<date and time>필드는 파일이 마지막으로 수정되었을 때의 적절한 날짜와 타임 스탬프를 포함해야한다. POSIX 로케일에서 필드는 다음 날짜 명령의 출력과 동일해야합니다.

date "+%b %e %H:%M"

... 지난 6 개월 동안 파일이 수정 된 경우 또는

date "+%b %e %Y"

이것을 고려하고 파일 이름에 줄 바꿈이 있으면 POSIX 지정 ls -q옵션을 올바르게 사용하는지 확인하십시오 . ls결과없이 정규 표현식을 준비하는 것이 상대적으로 쉽습니다 find.

d=$(date "+%b %e") y=$(date --date=yesterday "+%b %e")
echo "$d" "$y"

###OUTPUT###
Jul  5 Jul  4

grep이를 위해 오늘 또는 어제 날짜를 나타내는 문자열을 포함하는 행만 반환합니다. 다음 명령은 약간 추가합니다.

ls -alRcq | sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"

ls 옵션은 다음으로 구성됩니다.

  1. -a 로 시작하는 파일을 포함하여 디렉토리의 모든 파일을 반환합니다. .dot
  2. -l 긴 목록
  3. -R 모든 하위 디렉토리를 재귀 적으로 나열
  4. -c 액세스 시간이 아닌 수정 시간 표시
  5. -q파일 이름에 ?인쇄 할 수 없거나 \tab 문자 가 아닌 쉘 글로브를 반환

해당 결과는 다음과 일치 하는 |pipe파일을 통해 전달 sed됩니다.

  1. 경로명 앞의 빈 줄과 다음 줄
  2. 로 시작하는 행 - (즉 d, 디렉토리가 아닌 )date.
  3. 이름이 지정된 디렉토리에 실제로 필터링 한 파일이 포함되어 있지 않으면 경로 이름 행을 인쇄하지 않습니다.

결과는 다음과 같습니다.

ls -alRcq --color=always | 
sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"

###OUTPUT###
.:
-rw------- 1 mikeserv mikeserv   2086 Jul  4 10:52 .bash_history
-rw------- 1 mikeserv mikeserv   2657 Jul  4 15:20 .lesshst
-rw-r--r-- 1 mikeserv mikeserv    681 Jul  5 05:18 .zdirs
-rw------- 1 mikeserv mikeserv 750583 Jul  5 08:28 .zsh_history
-rw-r--r-- 1 mikeserv mikeserv    166 Jul  4 23:02 Terminology.log
-rw-r--r-- 1 mikeserv mikeserv 433568 Jul  4 13:34 shot-2014-06-22_17-10-16.jpg
-rw-r--r-- 1 mikeserv mikeserv 445192 Jul  4 13:34 shot-2014-06-22_17-11-06.jpg

./.cache/efreet:
-rw------- 1 mikeserv mikeserv  37325 Jul  4 22:51 desktop_localhost_C.eet
-rw------- 1 mikeserv mikeserv  37325 Jul  4 23:30 desktop_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv  24090 Jul  4 22:51 desktop_util_localhost_C.eet
-rw------- 1 mikeserv mikeserv  24090 Jul  4 23:30 desktop_util_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv  16037 Jul  4 23:30 icon_themes_localhost.eet
-rw------- 1 mikeserv mikeserv   3117 Jul  4 23:30 icons___efreet_fallback_localhost.eet
-rw------- 1 mikeserv mikeserv 768039 Jul  4 23:30 icons_gnome_localhost.eet
-rw------- 1 mikeserv mikeserv  18589 Jul  4 23:30 icons_hicolor_localhost.eet

./.config:
-rw-r--r-- 1 mikeserv mikeserv   30 Jul  4 19:10 pavucontrol.ini

./.config/chrome:
-rw-r--r-- 1 mikeserv mikeserv 94332179 Jul  4 13:36 conf.tar.lz4.bak

예, 물론 작동합니다 LS_COLORS- cron물론 우선 순위가 낮을 수도 있지만 옵션이 열려 있습니다.

어쨌든 이것은 다른 가능한 솔루션보다 몇 가지 중요한 이점을 제공합니다.

  1. 우선 find+ ls는 여러 번의 호출을 포함합니다. 이것은 단일 ls프로세스 만 포함 하므로 기본적으로 수행되는 모든 작업을 안정적으로 정렬 할 수 있기 때문에 sort부수적으로 이루어집니다.

  2. 모든 솔루션을 포함 find하고 sort있으며 ls거의 모든 작업을 두 번 수행하는 솔루션 입니다. ls그리고 find모두 모든 경로 및 해결할 수 stat있는 모든 파일을. ls그리고 sort모든 결과를 정렬합니다. 대신 싱글을 사용하는 것이 가장 좋습니다 ls.

  3. 물론 이 답변의 일부 datesed부분이 있습니다. 여기서 중요한 점은 어려운 부분을 수행하고 정규 표현식을 먼저 한 번만 얻은 다음 결과를 얻고 결과를 얻고 결과를 정렬하고 결과를 정렬하는 대신 단일 결과 목록 만 제거한다는 것입니다.

  4. 다른 솔루션과 마찬가지로 개행 문자가 포함 된 파일 이름은 손상되지 않습니다. 이 솔루션에는 다음에 설명 할 자체 경고 사항이 있지만 미세하고 쉽게 처리 할 수 ​​있습니다. 제 생각에는 이것이 가장 강력한 솔루션입니다.

위의 명령으로 인해 문제가 발생할 수있는 두 가지 경우가 있습니다. 첫 번째는 ?파일 이름에 globs가 포함 되어 있습니다. 이것은 이미 여기에 제공된 다른 것보다 더 강력한 솔루션이므로, 당신이 ?전혀 만날 가능성은 그 자체로 충분히 작습니다. 그러한 globs를 해결할 가능성이 있습니다 둘 이상의 파일 이름과 일치 할 수 있습니다. 이 주제에 대한 자세한 내용 은 이것을 참조하십시오 .

다른 가능성은 가양 성 (false positive)과 관련이 있습니다. 예를 들어, 검색중인 date문자열과 실제로 일치하는 파일 이름 이 grep있지만 그 당시 어느 날에도 실제로 수정되지 않은 경우 나는 그것이 문제가되고 있다고 생각하지 않지만 문제가 있다면 그것에 대해 물어보십시오.이를 처리하기 위해 정규식을보다 구체적으로 만들 수 있습니다.


0

find, xargs 및 ls의 조합을 실제로 사용할 수 있습니다.

다음은 샘플 명령입니다. find . -type f -print0 | xargs -0 ls -lt

  • find 현재 디렉토리 아래의 모든 파일을 재귀 적으로 찾습니다.
  • xargs는 ls한 번의 호출 로이 파일 목록을 명령에 전달합니다 (제공된 파일 find보다 적은 수의 리턴 ARG_MAX).
  • ls -lt 이 파일을 시간별로 정렬하고 출력 형식을 지정합니다.

시스템을 검색 ARG_MAX하려면 다음을 입력하십시오.

$ getconf ARG_MAX
> 2621440

-1
ls -l $(find /home/setefgge/public_html -type f -ctime -1 | sort)

1
ls자체 정렬을 수행하므로 find통과 출력을 파이핑하는 sort것은 쓸모가 없습니다. 또한 명령은 공백을 포함하는 파일 이름을 맹 글링하고 파일 이름이 너무 많으면 실패합니다.
Gilles 'SO- 악의를 멈춰라'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.