1 votos

Necesito leer un archivo delimitado por tabulaciones y mover los archivos a varias carpetas de salida en función de los valores del archivo de texto

Soy muy nuevo en AppleScript y en esta comunidad, así que espero que esta explicación tenga sentido.

Tengo un AppleScript que lee un archivo delimitado por tabulaciones con más de 20 campos y varios cientos de registros. El propósito del script es hacer coincidir cada nombre de archivo contenido en el archivo de texto con un archivo en una carpeta de entrada y mover esos archivos a una de las ocho carpetas de salida basándose en otro campo del archivo de texto.

Mi problema es que los nombres de los archivos en el archivo de texto tienen .jpg y los archivos de la carpeta de entrada han sido procesados para que contengan .png como la extensión. Cómo puedo cambiar el script para que ignore la extensión al cotejar los archivos o que la lista de entrada se convierta en .png cuando AppleScript crea una lista.

Aquí está el actual script. He tenido mucha ayuda para crear esto.

(*
gsbr.applescript

Process a tab-separated-values (.tsv) file of 23 columns and several hundred records to identify
"SP1" in the GSBR column, and add its associated filename for background replacement to a list.
That list then attempts to match filenames in a selected folder with the same name, and duplicate those
files to an outfolder for subsequent background replacement.
The script repeats this process looking for values "SP2" - "SP8"  using the same input folder but placing each SPx in a different output folder
*)

use framework "Foundation"
use AppleScript version "2.4" # Yosemite or later
use scripting additions

property NSString : a reference to current application's NSString
property NSCharacterSet : a reference to current application's NSCharacterSet
property NSArray : a reference to current application's NSArray
property istext : {"public.text", "public.plain-text"}
property adesktop : (path to desktop) as alias
property delim : tab

set moveList to {}
set rowItems to {}
set matchList1 to {}
set matchList2 to {}
set matchList3 to {}
set matchList4 to {}
set matchList5 to {}
set matchList6 to {}
set matchList7 to {}
set matchList8 to {}
set gsbr1List to NSArray's array()'s mutableCopy()
set gsbr2List to NSArray's array()'s mutableCopy()
set gsbr3List to NSArray's array()'s mutableCopy()
set gsbr4List to NSArray's array()'s mutableCopy()
set gsbr5List to NSArray's array()'s mutableCopy()
set gsbr6List to NSArray's array()'s mutableCopy()
set gsbr7List to NSArray's array()'s mutableCopy()
set gsbr8List to NSArray's array()'s mutableCopy()

-- by default, the invisibles is true, and other clauses are false by default
set myList to (choose file with prompt "Select file containing list:" of type istext default location adesktop without invisibles)
set inFolder to (choose folder with prompt "Select copy-from folder: " default location adesktop)

set theJobFolder to (choose folder with prompt "Select the Job folder" default location (path to desktop))
set jobName to name of (info for theJobFolder)

-- read the text file into a list of the images to duplicate
-- all 23 fields in a row are string list items
set moveList to (read myList as text using delimiter linefeed) -- text is utf-8 by default
-- extract just the header fields
set headerList to ((NSString's stringWithString:(item 1 of moveList))'s componentsSeparatedByString:delim)
-- and then the rows of data
set dataList to rest of moveList

-- get column number representing header fields of interest
-- assumption: Header fields are not already double-quoted
-- we add 1 because Objective-C arrays are zero-based
set gsbr1 to (headerList's indexOfObject:"GSBR") + 1
set gsbr2 to (headerList's indexOfObject:"GSBR") + 1
set gsbr3 to (headerList's indexOfObject:"GSBR") + 1
set gsbr4 to (headerList's indexOfObject:"GSBR") + 1
set gsbr5 to (headerList's indexOfObject:"GSBR") + 1
set gsbr6 to (headerList's indexOfObject:"GSBR") + 1
set gsbr7 to (headerList's indexOfObject:"GSBR") + 1
set gsbr8 to (headerList's indexOfObject:"GSBR") + 1
set fname to (headerList's indexOfObject:"FileName") + 1

-- process data rows
repeat with arow in dataList
    -- convert the row as text to individual list items so we can find gsbr1 and filename content
    set rowItems to my txt_to_list(arow, delim)
    -- retrieve gsbr1 code if present in the row items
    set rcode to (item gsbr1 of rowItems) as text
    -- and if found, then add the associated filename to the gsbr1List array
    if my to_uppercase(rcode) = "SP1" then
        (gsbr1List's addObject:((item fname of rowItems) as text))
    end if
    if my to_uppercase(rcode) = "SP2" then
        (gsbr2List's addObject:((item fname of rowItems) as text))
    end if
    if my to_uppercase(rcode) = "SP3" then
        (gsbr3List's addObject:((item fname of rowItems) as text))
    end if
    if my to_uppercase(rcode) = "SP4" then
        (gsbr4List's addObject:((item fname of rowItems) as text))
    end if
    if my to_uppercase(rcode) = "SP5" then
        (gsbr5List's addObject:((item fname of rowItems) as text))
    end if
    if my to_uppercase(rcode) = "SP6" then
        (gsbr6List's addObject:((item fname of rowItems) as text))
    end if
    if my to_uppercase(rcode) = "SP7" then
        (gsbr7List's addObject:((item fname of rowItems) as text))
    end if
    if my to_uppercase(rcode) = "SP8" then
        (gsbr8List's addObject:((item fname of rowItems) as text))
    end if

end repeat

-- convert the NSMutableArray back to an AppleScript list
set gsbr1List to gsbr1List as list
set gsbr2List to gsbr2List as list
set gsbr3List to gsbr3List as list
set gsbr4List to gsbr4List as list
set gsbr5List to gsbr5List as list
set gsbr6List to gsbr6List as list
set gsbr7List to gsbr7List as list
set gsbr8List to gsbr8List as list

(*
    Check to see if there are any items in each GSBR list. It there are, then create a subfolder inside
    the job folder and move the matching files from the list into that subfolder
*)

tell application "Finder"
    activate
    set matchList1 to (every item in folder inFolder whose name is in gsbr1List) as alias list
    if matchList1 != {} then -- we have at least one matching file, so create the folder
        set outFolder1 to (make new folder at theJobFolder with properties {name:jobName & "_SP1"})
        -- and iterate through the file to move them
        repeat with anItem in matchList1
            set moved_file to (move anItem to outFolder1)
        end repeat
    end if

    set matchList2 to (every item in folder inFolder whose name is in gsbr2List) as alias list
    if matchList2 != {} then -- we have at least one matching file, so create the folder
        set outFolder2 to (make new folder at theJobFolder with properties {name:jobName & "_SP2"})
        -- and iterate through the file to move them
        repeat with anItem in matchList2
            set moved_file to (move anItem to outFolder2)
        end repeat
    end if

    set matchList3 to (every item in folder inFolder whose name is in gsbr3List) as alias list
    if matchList3 != {} then -- we have at least one matching file, so create the folder
        set outFolder3 to (make new folder at theJobFolder with properties {name:jobName & "_SP3"})
        -- and iterate through the file to move them
        repeat with anItem in matchList3
            set moved_file to (move anItem to outFolder3)
        end repeat
    end if

    set matchList4 to (every item in folder inFolder whose name is in gsbr4List) as alias list
    if matchList4 != {} then -- we have at least one matching file, so create the folder
        set outFolder4 to (make new folder at theJobFolder with properties {name:jobName & "_SP4"})
        -- and iterate through the file to move them
        repeat with anItem in matchList4
            set moved_file to (move anItem to outFolder4)
        end repeat
    end if

    set matchList5 to (every item in folder inFolder whose name is in gsbr5List) as alias list
    if matchList5 != {} then -- we have at least one matching file, so create the folder
        set outFolder5 to (make new folder at theJobFolder with properties {name:jobName & "_SP5"})
        -- and iterate through the file to move them
        repeat with anItem in matchList5
            set moved_file to (move anItem to outFolder5)
        end repeat
    end if

    set matchList6 to (every item in folder inFolder whose name is in gsbr6List) as alias list
    if matchList6 != {} then -- we have at least one matching file, so create the folder
        set outFolder6 to (make new folder at theJobFolder with properties {name:jobName & "_SP6"})
        -- and iterate through the file to move them
        repeat with anItem in matchList6
            set moved_file to (move anItem to outFolder6)
        end repeat
    end if

    set matchList7 to (every item in folder inFolder whose name is in gsbr7List) as alias list
    if matchList7 != {} then -- we have at least one matching file, so create the folder
        set outFolder7 to (make new folder at theJobFolder with properties {name:jobName & "_SP7"})
        -- and iterate through the file to move them
        repeat with anItem in matchList7
            set moved_file to (move anItem to outFolder7)
        end repeat
    end if

    set matchList8 to (every item in folder inFolder whose name is in gsbr8List) as alias list
    if matchList8 != {} then -- we have at least one matching file, so create the folder
        set outFolder8 to (make new folder at theJobFolder with properties {name:jobName & "_SP8"})
        -- and iterate through the file to move them
        repeat with anItem in matchList8
            set moved_file to (move anItem to outFolder8)
        end repeat
    end if

end tell

-- cleanup
repeat with alist in {moveList, rowItems, matchList1, matchList2, matchList3, matchList4, matchList5, matchList6, matchList7, matchList8, gsbr1List, gsbr2List, gsbr3List, gsbr4List, gsbr5List, gsbr6List, gsbr7List, gsbr8List, headerList, dataList}
    set alist to {}
end repeat

display dialog "Script is done, check your Outfolders for results."
return

on txt_to_list(astr, delim)
    -- split the text row to its individual list items based on TSV delimiter (tab)
    return ((NSString's stringWithString:astr)'s componentsSeparatedByString:delim) as list
end txt_to_list

on to_uppercase(astr)
    -- force to uppercase and remove surrounding whitespace if present
    set nows to NSCharacterSet's whitespaceCharacterSet
    return ((NSString's stringWithString:astr)'s localizedUppercaseString()'s stringByTrimmingCharactersInSet:nows) as text
end to_uppercase

Aquí hay un ejemplo de archivo TSV de entrada de prueba: SequenceNumber FirstName LastName StudentID Teacher Grade HomeRoom Custom1 Custom2 Custom3 Custom4 P1 Q1 P2 Q2 P3 P4 Q4 Retouch Spray FileName GSBR
1 Faxxxxxxxxx Laxxxxxxxxx 14 Mi profesor 11 AAAAAAAAAA A 1 IMG_3002.jpg SP3 2 Fbxxxxxxxxx Lbxxxxxxxxx 42 Mi profesor 9 AAAAAAAAAA A 1 F 1 IMG_1018.jpg SP1 3 Fcxxxxxxxxx Lcxxxxxxxxx 15 Personal AAAAAAAAAA zz JBS_7611.jpg
4 Fdxxxxxxxxx Ldxxxxxxxxx 1 Mi profesor 12 AAAAAAAAAA NB IMG_1025.jpg SP1 5 Fexxxxxxxxx Lexxxxxxxxx 16 Mi profesor 11 AAAAAAAAAA B 1 R JBS_5002.jpg SP5 6 Ffxxxxxxxxx Lfxxxxxxxxx 2 Mi profesor 12 AAAAAAAAAA C 1 IMG_3003.jpg SP3 7 Fgxxxxxxxxx Lgxxxxxxxxx 17 Personal AAAAAAAAAA zz JBS_7612.jpg
8 Fhxxxxxxxxx Lhxxxxxxxxx 3 Mi profesor 12 AAAAAAAAAA B 1 R IMG_2550.jpg SP2 9 Fixxxxxxxxx Lixxxxxxxxx 4 Mi profesor 12 AAAAAAAAAA A 1 G 2 JBS_7613.jpg SP7

La carpeta con las imágenes que se van a mover tiene los mismos nombres de archivo, pero con la extensión .png

0voto

red_menace Puntos 111

Como se conocen las extensiones de los nombres de los archivos, basta con sustituirlas al obtener el nombre de la fila. En tu script eso está repartido y duplicado en varias líneas, así que lo he limpiado un poco:

use AppleScript version "2.4" # Yosemite or later
use framework "Foundation"
use scripting additions

property NSString : a reference to current application's NSString
property NSCharacterSet : a reference to current application's NSCharacterSet

global dataList, gsbrLists, indexes

on run
   initialize(true)
   process() -- do the stuff
   tell me to activate
   display dialog "Script is done, check your Outfolders for results."
   initialize(false) -- clear globals
end run

on initialize(flag) -- initialize or clear global variables
   set dataList to {} -- the rows
   set gsbrLists to {{}, {}, {}, {}, {}, {}, {}, {}} -- SP1-SP8
   set indexes to {} -- column indexes
   if flag is not true then return

   set myList to (choose file with prompt "Select the file containing the data list:" of type {"public.text", "public.plain-text"} default location (path to desktop))
   -- read the text file into a list of the images to duplicate
   set moveList to paragraphs of (read myList) -- text is utf-8 by default
   -- extract  column numbers of the desired header fields - note that Objective-C arrays are zero-based
   set headerList to ((NSString's stringWithString:(item 1 of moveList))'s componentsSeparatedByString:tab)
   set end of indexes to (headerList's indexOfObject:"GSBR") + 1
   set end of indexes to (headerList's indexOfObject:"FileName") + 1
   -- and then the rows of data
   set dataList to rest of moveList
end initialize

to process() -- process data rows
   set inFolder to (choose folder with prompt "Select the folder to copy from: " default location (path to desktop))
   set jobFolder to (choose folder with prompt "Select the Job folder:" default location (path to desktop))
   tell application "Finder" to set jobName to name of jobFolder
   repeat with aRow in dataList
      -- convert the row as text to individual list items so we can find gsbr and filename content
      set rowItems to ((NSString's stringWithString:aRow)'s componentsSeparatedByString:tab) as list
      if rowItems is not {""} then -- skip empty lines
         set fileName to (text 1 thru -5 of (item (last item of indexes) of rowItems)) & ".png" -- replace .jpg extension
         -- retrieve gsbr code if present in the row items
         set rowCode to upcaseAndTrim(item (first item of indexes) of rowItems)
         if rowCode is not "" then -- if found, add the filename to the associated gsbrLists list
            if rowCode = "SP1" then set end of (first item of gsbrLists) to fileName
            if rowCode = "SP2" then set end of (second item of gsbrLists) to fileName
            if rowCode = "SP3" then set end of (third item of gsbrLists) to fileName
            if rowCode = "SP4" then set end of (fourth item of gsbrLists) to fileName
            if rowCode = "SP5" then set end of (fifth item of gsbrLists) to fileName
            if rowCode = "SP6" then set end of (sixth item of gsbrLists) to fileName
            if rowCode = "SP7" then set end of (seventh item of gsbrLists) to fileName
            if rowCode = "SP8" then set end of (eighth item of gsbrLists) to fileName
         end if
      end if
   end repeat

   tell application "Finder" -- move matching files
      activate
      repeat with indx from 1 to (count gsbrLists)
         set matches to (every item of inFolder whose name is in (item indx of gsbrLists)) as alias list
         if matches != {} then -- we have at least one matching file, so create the folder
            try -- check if folder already exists
               set outFolder to ((jobFolder as text) & jobName & "_SP" & indx) as alias
            on error errmess -- nope
               log errmess
               set outFolder to (make new folder at jobFolder with properties {name:jobName & "_SP" & indx})
            end try
            move matches to outFolder -- and move 'em
         end if
      end repeat
   end tell
end process

to upcaseAndTrim(theString) -- convert to uppercase and trim whitespace
   return ((NSString's stringWithString:theString)'s localizedUppercaseString()'s stringByTrimmingCharactersInSet:(NSCharacterSet's whitespaceCharacterSet)) as text
end upcaseAndTrim

Utilicé listas en lugar de un montón de variables diferentes, lo que eliminó un montón de la duplicación y (con suerte) lo hizo un poco más simple. Realicé algunas pruebas, pero es posible que desee utilizar un conjunto de pruebas más pequeño antes de soltarlo en los archivos de producción.

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X