특정 시간 범위에서 변경된 파일을 나열하는 방법은 무엇입니까?


38

22.12.2011과 24.12.2011 사이에 변경된 모든 파일을 재귀 적으로 나열하려면 어떻게해야합니까?


6
'마지막 변경'을 의미하는 경우 솔루션에 대한 기회가 있습니다. 26.12.2011에서 파일이 수정 된 경우 지정된 범위 동안 파일이 수정되었는지도 알 수 없습니다. 매우 이국적인 파일 시스템이 없다면
William Pursell

답변:


25

일반적으로 디렉토리와 하위 디렉토리에서 파일을 재귀 적으로 찾을 때을 사용하십시오 find.

날짜 범위를 지정하는 가장 쉬운 방법 find은 범위 경계에서 파일을 작성하고 -newer술어를 사용하는 것 입니다.

touch -t 201112220000 start
touch -t 201112240000 stop
find . -newer start \! -newer stop

왜 첫 번째 출력을 무효화 -newer해야합니까?
Alexander Cska

@AlexanderCska 첫 번째 -newer는 부정되지 않고 두 번째 는 부정되지 않습니다. “보다 최신 start이지만 최신이 아닌 파일을 찾으십시오 stop.”
Gilles 'SO- 악마 그만해

Ok 부정은 이후 명령에서 작동합니다. 부정이 없으면 어떻게됩니까?
Alexander Cska

@AlexanderCska 그러면 start및 보다 새로운 파일을 얻을 수 있습니다 stop.
Gilles 'SO- 악마 그만

35

Gilles의 솔루션을 사용하고 사람 find (1)를 다시 읽은 후 더 간단한 해결책을 찾았습니다. 가장 좋은 옵션은 -newerXY입니다. m 및 t 플래그를 사용할 수 있습니다.

m   The modification time of the file reference
t   reference is interpreted directly as a time

그래서 해결책은

find . -type f -newermt 20111222 \! -newermt 20111225

하한을 포함하고 상한은 독점적이므로 1 일을 추가했습니다! 그리고 그것은 재귀 적입니다. 찾기 v4.5.9에서 잘 작동합니다.


멋진 트릭, 감사합니다! 수천 개의 파일이있는 디렉토리에 특정 키워드가 포함 된 최근 파일을 찾는 데 도움이되었습니다. find -newermt 20150212 \! -newermt 20150213 | xargs grep 'keyword' -m 50 -l( -m 50= 처음 50 줄에서 검색).
Rob W

@RobW : 사실 당신이 사용하는 파이프와 xargs 명령을 마련 할 수 -exec ... +있는 find(1)것처럼, : find -newermt 20150212 \! -newermt 20150213 -exec grep keyword -m 50 -l {} +. 이것은 동일하지만 저렴합니다.
TrueY

타임 스탬프를 큰 따옴표로 묶어야했습니다 (우분투 제니 얼에 있습니다 find 4.7.0-git).
IsaacS

13

이미 주어진 답변 외에도 날짜를 직접 지정할 수 있습니다.

find -type f -newermt "2011-12-22" \! -newermt "2011-12-24"

또는

find -type f -newermt "2011-12-22 00:00:00" \! -newermt "2011-12-24 13:23:00"

시간을 추가로 지정하려면


6

초 단위의 정밀도가 필요하지 않다고 가정하면 작동합니다.

find . -type f -mmin -$(((`date +%s`-`date -d 20111222 +"%s"`)/60)) \! -mmin +$(((`date +%s`-`date -d 20111224 +"%s"`)/60))

편집 : @ Elvex의 의견 이후로 변경 cmin되었습니다 mmin. 편집 : '\!' 밀집


흠 작동하지 않는 것 같습니다. 하위 디렉토리를 재귀 적으로 안내합니까?
클램프

예, 그것은 저에게 효과적입니다. 해당 시간 범위에서 실제로 파일을 수정 했습니까? 다른 시간 범위로 시도하십시오.
onur güngör

6
-cmin"상태 변경", -mmin"데이터 변경"입니다. 아마 당신이 원할 것입니다-mmin
Eelvex

3

find예를 들어 UTC 형식의 서버의 경우 ISO 형식의 날짜 시간을 사용할 수 있으므로 어디에서나 여러 시간의 오프셋을 지정할 수 있습니다. 또한 시간을 비교하고 있기 때문에 하루를 추가해야합니다.

find -type f -newermt 20111224T0800 \! -newermt 20111225T0800

0

중복으로 표시되어있는 질문에 직접 답변하는 것이 제한되어 있으므로 여기에 게시하는 이유에 유의하십시오. 이 답변은 "생성 날짜 [중복]에 따라 다른 폴더로 파일을 이동해야합니다"라는 질문에 대한 답변입니다.

대답은 합리적이지만 순수하게 찾기 명령에는 몇 가지 제한 사항이있었습니다. 파일 시스템이 ls를 수행하려고하는 메타 데이터를 보며 너무 많은 파일이있는 디렉토리를 통과하기 위해이 쉘 스크립트를 작성했습니다. 또한 일부 * nix 시스템은 ls를 실행하면 너무 많은 인수 오류가 발생하지 않습니다.

find 명령은 매우 강력하며 나열된 방법으로 시작했지만 디렉토리 전체에 너무 많은 데이터가있어서 모든 파일을 반복적으로 전달해야했습니다. 이것은 각 파일에 많은 불필요하게 전달됩니다. 나는 매년 한 화면을 수행하고 여러 번 찾기를 실행했지만 각 찾기에서 많은 오류가 발생했으며 찾기 중 하나가 이동하면 파일이 누락됩니다.

내 셸 스크립트는 파일을 4 자리 연도 및 2 자리 월과 함께 대상 디렉토리로 이동합니다. 몇 줄의 주석 처리를 제거하고 상대방을 주석 처리하여 2 자리로 쉽게 확장 할 수 있습니다. 찾기의 한 단계에서 이동을 수행했기 때문에 더 효율적이라고 생각하므로 여러 개의 찾기 명령과 디렉토리를 통과하는 것이 필요하지 않습니다.

#!/bin/bash
#We want to exit if there is no argument submitted
if [ -z "$1" ]
then
  echo no input file
  exit
fi

#destDir should be set to where ever you want the files to go
destDir="/home/user/destination"

#Get the month and year of modification time
#--format %y returns the modification date in the format:
# 2016-04-26 12:40:48.000000000 -0400
#We then take the first column, split by a white space with awk
date=`stat "$1" --format %y | awk '{ print $1 }'`

#This sets the year variable to the first column split on a - with awk
year=`echo $date | awk -F\- '{print $1 }'`
#This sets the month variable to the second column split on a - with awk
month=`echo $date | awk -F\- '{print $2 }'`
#This sets the day variable to the third column split on a - with awk
#This is commented out because I didn't want to add day to mine
#day=`echo $date | awk -F\- '{print $3 }'`

#Here we check if the destination directory with year and month exist
#If not then we want to create it with -p so the parent is created if
# it doesn't already exist
if [ ! -d $destDir/$year/$month ]
then
  mkdir -p $destDir/$year/$month || exit
fi

#This is the same as above but utilizes the day subdirectory
#Uncommented this out and comment out the similar code above
#if [ ! -d $destDir/$year/$month/$day ]
#then
#  mkdir -p $destDir/$year/$month$day || exit
#fi

#Echoing out what we're doing
#The uncommented is for just year/month and the commented line includes day
#Comment the first and uncomment the second if you need day
echo Moving $1 to $destDir/$year/$month
#echo Moving $1 to $destDir/$year/$month/$day

#Move the file to the newly created directory
#The uncommented is for just year/month and the commented line includes day
#Comment the first and uncomment the second if you need day
mv "$1" $destDir/$year/$month
#mv "$1" $destDir/$year/$month/$day

저장하고 실행 가능하게하면 다음과 같이이 스크립트를 호출 할 수 있습니다.

find /path/to/directory -type f -exec /home/username/move_files.sh {} \;

모든 찾기가 제공하는 것은 파일마다 하나의 실행이며 스크립트는 모든 결정을 내리기 때문에 찾기에 대해 newermt 옵션을 설정하는 것에 대해 걱정할 필요가 없습니다.

-type f를 선택하지 않으면 디렉토리가 이동하여 문제가 발생할 수 있습니다. 디렉토리 만 이동하려는 경우 -type d를 사용할 수도 있습니다. 유형을 설정하지 않으면 거의 확실하게 원치 않는 동작이 발생합니다.

이 스크립트는 필요에 맞게 조정되었다는 것을 기억하십시오 . 내 스크립트를 영감으로 사용하여 필요 스크립트에 더 적합하게 사용할 수 있습니다. 감사합니다!

고려 사항 : 무제한의 인수가 스크립트를 통과하게 하여 명령의 효율성을 크게 향상시킬 수 있습니다 . $ @ 변수를 전달하면 실제로 비교적 쉽습니다. 이 기능을 확장하면 find의 -exec + 함수를 사용하거나 xargs를 활용할 수 있습니다. 나는 그것을 빨리 구현하고 내 자신의 대답을 향상시킬 수 있지만 이것은 시작입니다.

이것은 원샷 스크립트 세션이므로 많은 개선이있을 수 있습니다. 행운을 빕니다!

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