如何覆盖文件夹中的所有文件?
How to Overwrite all files in a folder?
我正在使用以下方法复制文件:
on replace:sender
set allFiles to choose file with prompt "Please select your file:" with multiple selections allowed
repeat with theFile in allFiles
tell application "Finder"
set {name:fileName, name extension:nameExtension, file type:fileType} to theFile
if fileType is "png" or nameExtension is "png" then
set myPng to "~/Documents" & fileName as POSIX file
else
delay 0.2
tell current application's NSAlert's alloc's init()
its setMessageText:"Replace Photo"
its setInformativeText:"The file \"" & fileName & "\" is not a PNG file!"
its setAlertStyle:2
its setShowsSuppressionButton:false
its beginSheetModalForWindow:theWindow completionHandler:(missing value)
return
end tell
end if
if exists myPng then
delay 0.2
tell current application
display alert"There is already an older item named \""& fileName &"\" at this location." message ¬
"Do you want to replace it with the newer \"" & fileName & "\" one you're moving?" buttons {"Cancel", "Replace"} default button "Replace" as critical
set response to button returned of the result
if response is "Replace" then
delay 0.2
do shell script "rm -rf " & quoted form of POSIX path of myPng & space & "~/Documents" & myPng with administrator privileges
do shell script "mv " & quoted form of POSIX path of theFile & space & "~/Documents" with administrator privileges
end if
if response is "Cancel" then
return
end if
end tell
else
do shell script "mv " & quoted form of POSIX path of theFile & space & "~/Documents" with administrator privileges
end if
end tell
end repeat
end replace:
如果目标文件夹中有同名文件,用户会收到警报,但实际情况是每个复制的文件都会显示此警报,我只想显示此警报一次,只是正如 macOS 所做的那样,如果用户单击 "Replace" 按钮,所有文件将立即被替换。
最简单的方法是添加一个标志,默认为false
,并在用户按下"Replace"后设置为true
。
我删除了 rm
行,因为不需要它而且语法也不对。
on replace:sender
set replaceAll to false
set allFiles to choose file with prompt "Please select your file:" with multiple selections allowed
repeat with theFile in allFiles
tell application "Finder"
set {name:fileName, name extension:nameExtension, file type:fileType} to theFile
if fileType is "png" or nameExtension is "png" then
set myPng to "~/Documents" & fileName as POSIX file
else
delay 0.2
tell current application's NSAlert's alloc's init()
(its setMessageText:"Replace Photo")
(its setInformativeText:("The file \"" & fileName & "\" is not a PNG file!"))
(its setAlertStyle:2)
(its setShowsSuppressionButton:false)
(its beginSheetModalForWindow:theWindow completionHandler:(missing value))
return
end tell
end if
if exists myPng and replaceAll is false then
delay 0.2
tell current application
display alert "There is already an older item named \"" & fileName & "\" at this location." message ¬
"Do you want to replace it with the newer \"" & fileName & "\" one you're moving?" buttons {"Cancel", "Replace"} default button "Replace" as critical
set response to button returned of the result
if response is "Replace" then
delay 0.2
do shell script "mv " & quoted form of POSIX path of theFile & space & "~/Documents" with administrator privileges
set replaceAll to true
end if
if response is "Cancel" then
return
end if
end tell
else
do shell script "mv " & quoted form of POSIX path of theFile & space & "~/Documents" with administrator privileges
end if
end tell
end repeat
end replace:
您也可以使用 NSAlert(就像之前一样)和它的抑制按钮并跟踪处理程序中的状态,例如(运行 在脚本编辑器中的前景):
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
set buttonState to false
repeat -- forever, or at least until canceled
if buttonState then
display dialog "The suppression button state is currently " & buttonState buttons {"Cancel", "Reset", "OK"}
if button returned of the result is "Reset" then set buttonState to false
else
tell current application's NSAlert's alloc's init()
its setMessageText:"Alert"
its setInformativeText:"This alert is going to keep showing until you choose otherwise."
its setShowsSuppressionButton:true
its (suppressionButton's setTitle:"Skip the alerts")
its runModal()
set buttonState to (its suppressionButton's state()) as boolean
end tell
end if
end repeat
您的脚本无法编译,所以我无法对其进行测试以真正了解您在做什么,所以我希望我的想法与我的想法相符与下面。
但是,除此之外,我会直言不讳:你的脚本一团糟。你有一个 Finder 块,其中包含一些 AppleScriptObjC 代码,然后是一些 shell 函数调用......我认为你需要选择 one,然后更合理地组织代码,以便人们(尤其是您)能够理解正在发生的事情。
我通常避免使用 Finder 进行文件系统操作,但在这种情况下,这是有利的,因为它允许比较潜在的项目列表(由 whose
过滤器)和 已知 项目列表——这是其他应用程序不允许的(并且认为您希望将其与数字 64
进行比较)。这也意味着如果需要,可以 撤消 移动操作:
-- Bits of text for joining
-- Used for the alert dialogs
property lf : linefeed
property lft : linefeed & tab
property lf2 : lf & lf
property lf2t : lf2 & tab
property bullet : "›"
property li : bullet & space
-- Icon files, also used
-- for the alert dialogs
property CoreTypes : "/System/Library/CoreServices/CoreTypes.bundle"
property StopIcon : path to resource "AlertStopIcon.icns" in bundle CoreTypes
property NoteIcon : path to resource "AlertNoteIcon.icns" in bundle CoreTypes
on replace:sender
set prompt to "Please select some files:"
set fs to choose file with prompt prompt ¬
with multiple selections allowed
-- Get the directory in which the chosen files lie
set dir to (some item in fs & "::" as text)
set the text item delimiters to dir's POSIX path
-- Organise the files into two lists:
-- PNG files and non-PNG files
set PNGfs to {}
repeat with f in fs
get text items 2 thru -1 of f's POSIX path as text
set f's contents to the result
tell f to if its contents ends with ".png" then
set end of PNGfs to its contents
set its contents to null
end if
end repeat
set fs to every string in fs
set the text item delimiters to lft & li
if fs ≠ {} then display dialog ["The following files ", ¬
"are not PNG files and will be ignored:", lf2t, ¬
li & fs] as text with title ["Oops…!"] buttons ¬
["D'oh!"] with icon NoteIcon default button 1
if PNGfs = {} then return -- Nothing to move
tell application id "com.apple.Finder"
set here to dir as alias -- The source folder
set there to the (path to the documents folder) -- Destination folder
-- Enumerate files that might be replaced
set duplicates to the name of every file ¬
in there whose name is in PNGfs
if duplicates ≠ {} then tell (display dialog contents ¬
of ["The following files in ", here's POSIX path, ¬
" share names with files in ", there's POSIX path, ¬
":", lf2t & li & duplicates & lf2, "Do you want ", ¬
"to:", lft, "• Move all files anyway, replacing ", ¬
"the ones in ", there's POSIX path, ";", lft, "•", ¬
" Move only the files that can be moved without ", ¬
"replacing anything; OR", lft, "• Don't move any", ¬
" of the files for now ?"] as text ¬
with title ["Replace Existing Files?"] ¬
buttons ["Replace", "Keep", "Abort"] ¬
default button 1 with icon StopIcon) ¬
to set do to its button returned
-- If the user aborts, the script terminates.
-- If the user elects to replace existing files,
-- then we move those existing files to the trash.
-- If the user wishes to keep the existing files,
-- they remain in place. Either way, the final
-- operation is the same: move the files without
-- replacing anything.
if do = "Abort" then return 0 -- No files moved
if do = "Replace" then delete ¬
(files in there whose ¬
name is in ¬
duplicates)
move the (files in here whose ¬
name is in PNGfs) to ¬
there without replacing
end tell
end replace:
这样做可以避免重复循环,因此每组分组事件只会出现一个对话框(如果用户选择了错误类型的文件;如果存在覆盖文件的风险)。
事实上,您甚至可以摆脱用于按文件类型将列表分成两部分的第一个重复循环:choose file
命令有一个名为 of type
的参数,您可以在其中可以指定一种或多种文件类型,用户的选择将被限制为:
set fs to choose file with prompt prompt ¬
with multiple selections allowed ¬
of type ["png"] --OR:["public.png"]
"public.png"
是 PNG 文件的 uniform type identifier。
我正在使用以下方法复制文件:
on replace:sender
set allFiles to choose file with prompt "Please select your file:" with multiple selections allowed
repeat with theFile in allFiles
tell application "Finder"
set {name:fileName, name extension:nameExtension, file type:fileType} to theFile
if fileType is "png" or nameExtension is "png" then
set myPng to "~/Documents" & fileName as POSIX file
else
delay 0.2
tell current application's NSAlert's alloc's init()
its setMessageText:"Replace Photo"
its setInformativeText:"The file \"" & fileName & "\" is not a PNG file!"
its setAlertStyle:2
its setShowsSuppressionButton:false
its beginSheetModalForWindow:theWindow completionHandler:(missing value)
return
end tell
end if
if exists myPng then
delay 0.2
tell current application
display alert"There is already an older item named \""& fileName &"\" at this location." message ¬
"Do you want to replace it with the newer \"" & fileName & "\" one you're moving?" buttons {"Cancel", "Replace"} default button "Replace" as critical
set response to button returned of the result
if response is "Replace" then
delay 0.2
do shell script "rm -rf " & quoted form of POSIX path of myPng & space & "~/Documents" & myPng with administrator privileges
do shell script "mv " & quoted form of POSIX path of theFile & space & "~/Documents" with administrator privileges
end if
if response is "Cancel" then
return
end if
end tell
else
do shell script "mv " & quoted form of POSIX path of theFile & space & "~/Documents" with administrator privileges
end if
end tell
end repeat
end replace:
如果目标文件夹中有同名文件,用户会收到警报,但实际情况是每个复制的文件都会显示此警报,我只想显示此警报一次,只是正如 macOS 所做的那样,如果用户单击 "Replace" 按钮,所有文件将立即被替换。
最简单的方法是添加一个标志,默认为false
,并在用户按下"Replace"后设置为true
。
我删除了 rm
行,因为不需要它而且语法也不对。
on replace:sender
set replaceAll to false
set allFiles to choose file with prompt "Please select your file:" with multiple selections allowed
repeat with theFile in allFiles
tell application "Finder"
set {name:fileName, name extension:nameExtension, file type:fileType} to theFile
if fileType is "png" or nameExtension is "png" then
set myPng to "~/Documents" & fileName as POSIX file
else
delay 0.2
tell current application's NSAlert's alloc's init()
(its setMessageText:"Replace Photo")
(its setInformativeText:("The file \"" & fileName & "\" is not a PNG file!"))
(its setAlertStyle:2)
(its setShowsSuppressionButton:false)
(its beginSheetModalForWindow:theWindow completionHandler:(missing value))
return
end tell
end if
if exists myPng and replaceAll is false then
delay 0.2
tell current application
display alert "There is already an older item named \"" & fileName & "\" at this location." message ¬
"Do you want to replace it with the newer \"" & fileName & "\" one you're moving?" buttons {"Cancel", "Replace"} default button "Replace" as critical
set response to button returned of the result
if response is "Replace" then
delay 0.2
do shell script "mv " & quoted form of POSIX path of theFile & space & "~/Documents" with administrator privileges
set replaceAll to true
end if
if response is "Cancel" then
return
end if
end tell
else
do shell script "mv " & quoted form of POSIX path of theFile & space & "~/Documents" with administrator privileges
end if
end tell
end repeat
end replace:
您也可以使用 NSAlert(就像之前一样)和它的抑制按钮并跟踪处理程序中的状态,例如(运行 在脚本编辑器中的前景):
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
set buttonState to false
repeat -- forever, or at least until canceled
if buttonState then
display dialog "The suppression button state is currently " & buttonState buttons {"Cancel", "Reset", "OK"}
if button returned of the result is "Reset" then set buttonState to false
else
tell current application's NSAlert's alloc's init()
its setMessageText:"Alert"
its setInformativeText:"This alert is going to keep showing until you choose otherwise."
its setShowsSuppressionButton:true
its (suppressionButton's setTitle:"Skip the alerts")
its runModal()
set buttonState to (its suppressionButton's state()) as boolean
end tell
end if
end repeat
您的脚本无法编译,所以我无法对其进行测试以真正了解您在做什么,所以我希望我的想法与我的想法相符与下面。
但是,除此之外,我会直言不讳:你的脚本一团糟。你有一个 Finder 块,其中包含一些 AppleScriptObjC 代码,然后是一些 shell 函数调用......我认为你需要选择 one,然后更合理地组织代码,以便人们(尤其是您)能够理解正在发生的事情。
我通常避免使用 Finder 进行文件系统操作,但在这种情况下,这是有利的,因为它允许比较潜在的项目列表(由 whose
过滤器)和 已知 项目列表——这是其他应用程序不允许的(并且认为您希望将其与数字 64
进行比较)。这也意味着如果需要,可以 撤消 移动操作:
-- Bits of text for joining
-- Used for the alert dialogs
property lf : linefeed
property lft : linefeed & tab
property lf2 : lf & lf
property lf2t : lf2 & tab
property bullet : "›"
property li : bullet & space
-- Icon files, also used
-- for the alert dialogs
property CoreTypes : "/System/Library/CoreServices/CoreTypes.bundle"
property StopIcon : path to resource "AlertStopIcon.icns" in bundle CoreTypes
property NoteIcon : path to resource "AlertNoteIcon.icns" in bundle CoreTypes
on replace:sender
set prompt to "Please select some files:"
set fs to choose file with prompt prompt ¬
with multiple selections allowed
-- Get the directory in which the chosen files lie
set dir to (some item in fs & "::" as text)
set the text item delimiters to dir's POSIX path
-- Organise the files into two lists:
-- PNG files and non-PNG files
set PNGfs to {}
repeat with f in fs
get text items 2 thru -1 of f's POSIX path as text
set f's contents to the result
tell f to if its contents ends with ".png" then
set end of PNGfs to its contents
set its contents to null
end if
end repeat
set fs to every string in fs
set the text item delimiters to lft & li
if fs ≠ {} then display dialog ["The following files ", ¬
"are not PNG files and will be ignored:", lf2t, ¬
li & fs] as text with title ["Oops…!"] buttons ¬
["D'oh!"] with icon NoteIcon default button 1
if PNGfs = {} then return -- Nothing to move
tell application id "com.apple.Finder"
set here to dir as alias -- The source folder
set there to the (path to the documents folder) -- Destination folder
-- Enumerate files that might be replaced
set duplicates to the name of every file ¬
in there whose name is in PNGfs
if duplicates ≠ {} then tell (display dialog contents ¬
of ["The following files in ", here's POSIX path, ¬
" share names with files in ", there's POSIX path, ¬
":", lf2t & li & duplicates & lf2, "Do you want ", ¬
"to:", lft, "• Move all files anyway, replacing ", ¬
"the ones in ", there's POSIX path, ";", lft, "•", ¬
" Move only the files that can be moved without ", ¬
"replacing anything; OR", lft, "• Don't move any", ¬
" of the files for now ?"] as text ¬
with title ["Replace Existing Files?"] ¬
buttons ["Replace", "Keep", "Abort"] ¬
default button 1 with icon StopIcon) ¬
to set do to its button returned
-- If the user aborts, the script terminates.
-- If the user elects to replace existing files,
-- then we move those existing files to the trash.
-- If the user wishes to keep the existing files,
-- they remain in place. Either way, the final
-- operation is the same: move the files without
-- replacing anything.
if do = "Abort" then return 0 -- No files moved
if do = "Replace" then delete ¬
(files in there whose ¬
name is in ¬
duplicates)
move the (files in here whose ¬
name is in PNGfs) to ¬
there without replacing
end tell
end replace:
这样做可以避免重复循环,因此每组分组事件只会出现一个对话框(如果用户选择了错误类型的文件;如果存在覆盖文件的风险)。
事实上,您甚至可以摆脱用于按文件类型将列表分成两部分的第一个重复循环:choose file
命令有一个名为 of type
的参数,您可以在其中可以指定一种或多种文件类型,用户的选择将被限制为:
set fs to choose file with prompt prompt ¬
with multiple selections allowed ¬
of type ["png"] --OR:["public.png"]
"public.png"
是 PNG 文件的 uniform type identifier。