최신 파일 일치 패턴을 찾기 위한 Bash 기능
Bash에서는 특정 패턴과 일치하는 최신 파일의 파일 이름을 반환하는 함수를 만들고 싶습니다.예를 들어 다음과 같은 파일 디렉토리가 있습니다.
Directory/
a1.1_5_1
a1.2_1_4
b2.1_0
b2.2_3_4
b2.3_2_0
저는 'b2'로 시작하는 최신 파일을 원합니다.bash에서 이걸 어떻게 하나요?이것을 내 안에 가지고 있어야 합니다.~/.bash_profile
대본.
그ls
명령에 매개 변수가 있습니다.-t
시간별로 정렬합니다.그런 다음 첫 번째(가장 최근의) 항목을 사용할 수 있습니다.head -1
.
ls -t b2* | head -1
하지만 조심하세요:ls의 출력을 구문 분석하면 안 되는 이유
제 개인적인 의견: 파싱ls
파일 이름에 공백이나 줄 바꿈과 같은 재미있는 문자가 포함될 수 있는 경우 위험합니다.
파일 이름에 재미있는 문자가 포함되지 않도록 보장할 수 있는 경우(파일 생성 방법을 제어하기 때문일 수 있음) 구문 분석ls
꽤 안전합니다.
다양한 상황에서 많은 사람이 여러 시스템에서 실행해야 하는 스크립트를 개발하는 경우 구문 분석하지 마십시오.ls
.
안전한 방법은 다음과 같습니다.디렉토리에서 최신(최신, 가장 빠른, 가장 오래된) 파일을 찾는 방법은 무엇입니까?
unset -v latest
for file in "$dir"/*; do
[[ $file -nt $latest ]] && latest=$file
done
의 조합find
그리고.ls
에 적합한
- 줄 바꿈 없이 파일 이름
- 파일의 양이 많지 않음
- 그다지 길지 않은 파일 이름
해결책:
find . -name "my-pattern" -print0 |
xargs -r -0 ls -1 -t |
head -1
그것을 분해해 보겠습니다.
와 함께find
다음과 같은 모든 흥미로운 파일을 일치시킬 수 있습니다.
find . -name "my-pattern" ...
그 다음에 사용-print0
우리는 모든 파일 이름을 안전하게 전달할 수 있습니다.ls
다음과 같이:
find . -name "my-pattern" -print0 | xargs -r -0 ls -1 -t
추가의find
검색 매개 변수 및 패턴을 여기에 추가할 수 있습니다.
find . -name "my-pattern" ... -print0 | xargs -r -0 ls -1 -t
ls -t
파일을 수정 시간별로 정렬하고(먼저 정렬) 한 줄에 하나씩 인쇄합니다.사용할 수 있습니다.-c
생성 시간을 기준으로 정렬합니다.참고: 새 줄이 포함된 파일 이름으로 구분됩니다.
마침내.head -1
정렬된 목록의 첫 번째 파일을 가져옵니다.
참고: xargs
인수 목록의 크기에 대한 시스템 제한을 사용합니다.이 크기가 초과되면,xargs
부를 것입니다ls
여러 번이렇게 하면 정렬이 중단되고 최종 출력도 중단될 수 있습니다.달려.
xargs --show-limits
시스템의 제한을 확인합니다.
참고 2: 사용find . -maxdepth 1 -name "my-pattern" -print0
하위 폴더를 통해 파일을 검색하지 않으려는 경우
참고 3: @starfri가 지적한 바와 같이 --r
을 지지하는 주장.xargs
의 통화를 막고 있습니다.ls -1 -t
일치하는 파일이 없는 경우find
제안 감사합니다.
필요한 Bash 기능을 구현할 수 있습니다.
# Print the newest file, if any, matching the given pattern
# Example usage:
# newest_matching_file 'b2*'
# WARNING: Files whose names begin with a dot will not be checked
function newest_matching_file
{
# Use ${1-} instead of $1 in case 'nounset' is set
local -r glob_pattern=${1-}
if (( $# != 1 )) ; then
echo 'usage: newest_matching_file GLOB_PATTERN' >&2
return 1
fi
# To avoid printing garbage if no files match the pattern, set
# 'nullglob' if necessary
local -i need_to_unset_nullglob=0
if [[ ":$BASHOPTS:" != *:nullglob:* ]] ; then
shopt -s nullglob
need_to_unset_nullglob=1
fi
newest_file=
for file in $glob_pattern ; do
[[ -z $newest_file || $file -nt $newest_file ]] \
&& newest_file=$file
done
# To avoid unexpected behaviour elsewhere, unset nullglob if it was
# set by this function
(( need_to_unset_nullglob )) && shopt -u nullglob
# Use printf instead of echo in case the file name begins with '-'
[[ -n $newest_file ]] && printf '%s\n' "$newest_file"
return 0
}
기본 제공되는 Bash만 사용하며 이름에 줄이나 다른 비정상적인 문자가 포함된 파일을 처리해야 합니다.
find 명령을 사용합니다.
4하면 Bash 4.2+를 사용합니다.-printf '%T+ %p\n'
파일 타임스탬프 값입니다.
find $DIR -type f -printf '%T+ %p\n' | sort -r | head -n 1 | cut -d' ' -f2
예:
find ~/Downloads -type f -printf '%T+ %p\n' | sort -r | head -n 1 | cut -d' ' -f2
더 유용한 스크립트는 다음 웹 사이트에서 찾을 수 있는 스크립트를 참조하십시오.
사용할 수 있습니다.stat
전면에 파일 시간이 추가된 파일 글러브와 데코레이션:
$ stat -f "%m%t%N" b2* | sort -rn | head -1 | cut -f2-
코멘트에 명시된 바와 같이, 최고의 크로스 플랫폼 솔루션은 Python, Perl, Ruby 스크립트를 사용하는 것일 수 있습니다.
그런 점에서 루비는 작고 버리는 스크립트를 쓰는 것처럼 매우 어색하지만 명령 줄에서 바로 파이썬이나 펄의 힘을 가지고 있기 때문에 사용하는 편입니다.
여기 루비가 있습니다.
ruby -e '
# index [0] for oldest and [-1] for newest
newest=Dir.glob("*").
reject { |f| File.directory?(f)}.
sort_by { |f| File.birthtime(f) rescue File.mtime(f)
}[-1]
p newest'
그러면 현재 작업 디렉터리에 있는 최신 파일이 만들어집니다.
또한 다음을 사용하여 글로벌을 재귀적으로 만들 수 있습니다.**/*
glob
" 또일치는파제한다니합일로는하다▁with"로 일치하는 파일로 합니다.b2*
,주요사항
패턴과 일치하는 디렉토리에서 최신 파일을 찾기 위한 Bash 함수
#1. Make a bash function:
newest_file_matching_pattern(){
find $1 -name "$2" -print0 | xargs -0 ls -1 -t | head -1
}
#2. Setup a scratch testing directory:
mkdir /tmp/files_to_move;
cd /tmp/files_to_move;
touch file1.txt;
touch file2.txt;
touch foobar.txt;
#3. invoke the function:
result=$(newest_file_matching_pattern /tmp/files_to_move "file*")
printf "result: $result\n"
인쇄:
result: /tmp/files_to_move/file2.txt
또는 파이썬 인터프리터에 하청을 주는 취약한 바쉬샵 트릭이 당신의 각도에 더 가깝다면, 이것은 동일한 작업을 수행합니다.
#!/bin/bash
function newest_file_matching_pattern {
python - <<END
import glob, os, re
print(sorted(glob.glob("/tmp/files_to_move/file*"), key=os.path.getmtime)[0]);
END
}
result=$(newest_file_matching_pattern)
printf "result: $result\n"
인쇄:
result: /tmp/files_to_move/file2.txt
이름한 파일이 등)\n
문자는 이런 종류의 구문 분석을 혼란스럽게 만들 수 있습니다.Perl로 실행하는 방법은 다음과 같습니다.
perl -le '@sorted = map {$_->[0]}
sort {$a->[1] <=> $b->[1]}
map {[$_, -M $_]}
@ARGV;
print $sorted[0]
' b2*
이것은 슈바르츠식 변형입니다.
Google 사용자:
ls -t | head -1
-t
합니다.head -1
번째 합니다.
이것을 달성하는 훨씬 더 효율적인 방법이 있습니다.다음 명령을 고려합니다.
find . -cmin 1 -name "b2*"
이 명령은 "b2*"에서 와일드카드 검색으로 정확히 1분 전에 생성된 최신 파일을 찾습니다.지난 이틀 동안의 파일을 원한다면 아래 명령을 사용하는 것이 좋습니다.
find . -mtime 2 -name "b2*"
"."는 현재 디렉토리를 나타냅니다.이게 도움이 되길 바랍니다.
언급URL : https://stackoverflow.com/questions/5885934/bash-function-to-find-newest-file-matching-pattern
'source' 카테고리의 다른 글
markForCheck()와 detectChanges()의 차이점은 무엇입니까? (0) | 2023.05.27 |
---|---|
postgres의 테이블에 대한 허가 쿼리 (0) | 2023.05.27 |
val()을 사용하여 선택 값을 설정할 때 jquery change 이벤트가 트리거되지 않는 이유는 무엇입니까? (0) | 2023.05.27 |
Angular 2.0 라우터가 브라우저를 다시 로드하는 데 작동하지 않음 (0) | 2023.05.27 |
기본 브라우저에서 웹 페이지 열기 (0) | 2023.05.27 |