내 사진 라이브러리의 모든 파일을 읽고 실제로 존재하는지 확인하고 싶습니다. 나의 AppleScript 지식은 지금까지 괜찮 았고 이것을 깨닫기에 충분합니다. 그러나 이것은 많은 수의 파일에 관한 것이며 AppleScript는 이것에 적합하지 않습니다. 10,000 개 파일의 경우 20 분이 걸립니다. 그래서 저는 쉘 스크립트로 스크립트의 가장 중요한 부분을하기로 결정했습니다 .... 하지만 저는 유닉스 세계에 익숙하지 않아서 이틀간의 인터넷 검색 크래시 코스를 완료해야했습니다. 하지만 이제 여러분의 도움을 받고 싶은 지점에 도달했습니다!
내 실험은 다음과 같습니다.
모든 것을 AppleScript에 포함하겠습니다. 많은 파일을 편집해야하므로 단계 사이에 임시 텍스트 파일로 저장하는 것이 더 나을 것이라고 생각했습니다. 첫 번째 단계에서는 데이터베이스를 읽습니다. 1 초 밖에 걸리지 않습니다.
경로 | 이름 | 아이디 | 참조 | 외부 하드 디스크 이름
2018/03/27/20180327-122110/TVTower.JPG|TVTower|hA3CRRfPSS6FXqk7IDobLw|0|
Projekte/BCT 2017/BCT Fotos GPS/BCT_GPS_001.JPG|BCT_A_GPS_001|hyvsQgiaR4e3ou7XIZ%Gjg|1|Media
Leo/Carmina Burana/Leo UdK/IMG_0626.JPG|IMG_0626|j7342DtGSmag7YVLN1Nzhg|1|Logic
Users/spazek/Desktop/WeTransfer/Bild 2.png|Bild 2|Sa7rckZiSd2bIiRVO0JidA|1|macOS
다음 단계에서 누락 된 경로 부분이 추가됩니다.
/Users/spazek/Pictures/Fotos Library.photoslibrary/Masters/2018/03/27/20180327-122110/TVTower.JPG|TVTower|hA3CRRfPSS6FXqk7IDobLw|0|
/Volumes/Logic/Projekte/BCT 2017/BCT Fotos GPS/BCT_GPS_001.JPG|BCT_A_GPS_001|hyvsQgiaR4e3ou7XIZ%Gjg|1|Media
/Volumes/Logic/Leo/Carmina Burana/Leo UdK/IMG_0626.JPG|IMG_0626|j7342DtGSmag7YVLN1Nzhg|1|Logic
/Users/spazek/Desktop/WeTransfer/Bild 2.png|Bild 2|Sa7rckZiSd2bIiRVO0JidA|1|macOS
Mac에서 10,000 개의 파일에 대한 솔루션을 사용하는 데 2:30 분이 걸립니다. 실행중인 AppleScript가 과부하 한계에있는 것 같습니다! Terminal.app에서 실행하면 창 헤더에서 awk와 bash 사이에 항상 점프가 있음을 알 수 있습니다. 뭔가 잘못된 것 같아요.
다음 단계에서는 경로가 있는지 확인하고 싶습니다. 이전 스크립트와 유사하므로 시간이 조금 더 걸립니다. 마지막 단계에서는 누락 된 파일을 텍스트 파일에 씁니다.
.
sqlite3 -separator $'|' /Users/spazek/Desktop/xsystx/systphotos.db 'select RKMaster.imagePath, RKMaster.name, RKMaster.uuid, RKMaster.fileIsReference, ( select RKVolume.name from RKVolume where RKVolume.modelId = RKMaster.volumeId) from RKMaster' > /Users/spazek/Desktop/filelist1.txt
.
while read f; do
var1=`echo "$f" | awk -F[=\|] '{print $1}'`;
var2=`echo "$f" | awk -F[=\|] '{print $2}'` ;
var3=`echo "$f" | awk -F[=\|] '{print $3}'` ;
var4=`echo "$f" | awk -F[=\|] '{print $4}'` ;
var5=`echo "$f" | awk -F[=\|] '{print $5}'` ;
if [ "$var4" == 0 ] ; then
echo /Users/spazek/Pictures/Fotos Library.photoslibrary/Masters/"${f}" ;
else
if [ "$var5" == "macOS" ]; then
echo /"${f}" ;
else
echo /Volumes/"$var5"/"${f}";
fi;
fi >> /Users/spazek/Desktop/filelist2.txt;
done < /Users/spazek/Desktop/filelist1.txt
.
while read f; do
var1=`echo "$f" | awk -F[=\|] '{print $1}'`;
var3=`echo "$f" | awk -F[=\|] '{print $3}'` ;
test -f "$var1" || echo "$var1|$var3" >> /Users/spazek/Desktop/filelist3.txt;
done < /Users/spazek/Desktop/filelist2.txt
.
while read f; do
var1=`echo "$f" | awk -F[=\|] '{print $1}'`;
var2=`echo "$f" | awk -F[=\|] '{print $2}'` ;
test -f "$var1" || echo "Name = $var2 \n Path = $var1 \n";
done > ~/Desktop/Photos_MissingItems.txt < /Users/spazek/Desktop/filelist3.txt
스크립트 개선을위한 도움이나 제안에 대해 매우 기쁩니다.
GNU awk
버전 4 이상이 설치되어있는 경우 표준 awk 또는 GNU-enhanced에없는 기능을 제공하는 외부 모듈을로드 할 수 있습니다 awk
. 라는 모듈을 포함하여 일련의 모듈이 함께 제공됩니다 filefuncs
. filefuncs
모듈은 포함 awk
시스템에 래퍼 stat
(그들이 존재 여부 포함) 파일에 대한 정보를 얻기 위해 사용할 수있는 기능.
다음 awk
스크립트는 filefuncs
모듈을 로드하고 각 입력 줄을 읽고 5 번째 열을 확인하여 각 입력 파일 이름에 추가 할 경로를 결정하고 파일이 있는지 확인합니다. 그렇다면 전체 경로와 파일 이름을 stdout에 인쇄합니다. 그렇지 않으면 stderr에 경고 메시지를 출력합니다.
paths
연관 배열 (일명 "해시"또는 "해시 배열") 및 기본 사전 보류 경로는 의도 일에 대해 최선의 추측이다. 필요에 따라 조정하십시오. 귀하의 의견 중 하나에서 말한 내용이 아니라 제공된 샘플의 데이터 (Media-> / Volumes / Logic의 명백한 실수조차도)와 일치합니다. 의견이 정확하면 코드를 단순화 할 수 있습니다.
#!/usr/bin/awk -f
# this will only work with GNU awk >= version 4.0
@load "filefuncs"
BEGIN {
FS=OFS="|";
paths["default"] = "/Users/spazek/Pictures/Fotos Library.photoslibrary/Masters/";
paths["Logic"] = "/Volumes/Logic/";
paths["Media"] = "/Volumes/Logic/";
paths["macOS"] = "/";
}
{ if ($5 in paths) {
filename = paths[$5] $1;
} else { # $5 not known in paths array, use a default
filename = paths["default"] $1;
}
# try to stat the file. get the return code in variable 'rc' and error
# string (if any) in 'error'.
rc=stat(filename,fstat);
error=ERRNO; # oddly, ERRNO is a string, not a number.
if (rc == -1) { # return code of -1 is "No such file or directory"
# print warning to stdout and skip to next input line
print filename ": " error > "/dev/stderr"
next;
};
# filename exists, do something with filename.
print filename, $2, $3, $4, $5;
}
예를 들어으로 저장 ./exists.awk
하고 chmod +x
(셸 스크립트에서와 동일 하게) 실행 가능하게 만들고 다음 과 같이 실행하십시오.
./exists.awk /Users/spazek/Desktop/filelist1.txt
또는 sqlite3를 직접 파이프하십시오.
sqlite3 -separator $'|' /Users/spazek/Desktop/xsystx/systphotos.db \
'select RKMaster.imagePath, RKMaster.name, RKMaster.uuid, RKMaster.fileIsReference, ( select RKVolume.name from RKVolume where RKVolume.modelId = RKMaster.volumeId) from RKMaster' \
| ./exists.awk
awk
요즘 Mac OS에 어떤 버전이 제공 되는지 모르겠습니다 . Free Software Foundation이 GPLv3 라이선스를 사용하기로 전환하기 전부터 BSD awk
또는 GNU의 고대 버전 일 가능성이 높습니다 awk
(이것이 Mac이 bash
현재 bash
버전 4가 아닌 고대 v3에 멈춰있는 이유입니다. 애플이 할 수 있기 때문이 아닙니다.) 마에 가 있기 때문에 업그레이드 bash는, 그건 하지 않습니다 . 사용 양조 는 GNU의 이후 버전이 필요한 경우 bash
또는 awk
).
어쨌든 GNU awk> = v4.0이 설치되어 있지 않다면 모든 버전의 perl
.
다음 perl
스크립트는 비표준 perl 모듈이나 기능을 사용하지 않으며, perl에는 파일 존재 여부를 테스트하기위한 연산자와 유사한 연산자가 있으므로 perl
의 내장 stat()
함수 를 사용할 필요도 없습니다 sh
. -e
여기에서 파일의 존재를 테스트 하는 연산자를 사용할 것 입니다 sh
.
#!/usr/bin/perl
use strict;
# declare %paths hash
my %paths = (
"default" => "/Users/spazek/Pictures/Fotos Library.photoslibrary/Masters/",
"Media" => "/Volumes/Logic/",
"Logic" => "/Volumes/Logic/",
"macOS" => "/",
);
# main loop, read in each line of input and process it.
while(<>) {
chomp; # strip trailing linefeed from end-of-line
my $filename=''; # declare $filename to belong to this scope
# split input on "|" characters
my ($path,$name,$id,$reference,$diskname) = split /\|/;
if (defined($paths{$diskname})) {
$filename = $paths{$diskname} . $path;
} else { # diskname not known in %paths hash, use a default
$filename = paths{"default"} . $path;
}
if (! -e $filename) {
# print warning to stderr and skip to next input line
warn "$filename: No such file or directory\n";
next;
};
# filename exists, do something with filename.
print join('|', $filename, $id, $reference, $diskname), "\n";
}
다시, 저장 exists.pl
및과 그것을 실행하기 chmod +x
. 다음으로 실행 :
./exists.pl /Users/spazek/Desktop/filelist1.txt
이 두 스크립트 중 하나는 while read
또는 유사한 루프를 사용하는 쉘 스크립트보다 수백 또는 수천 배 더 빠릅니다 .
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다