Dividi file csv usando il servizio Automator (Menu contestuale del Finder)

2

Sto tentando di creare un servizio di per Finder con il menu di scelta rapida che consente di dividere qualsiasi file csv selezionato, mentre copia nell'intestazione originale nella parte superiore di ogni file.

Il mio attuale tentativo è di far funzionare Automator questo script Bash Shell :

#!/bin/bash

FILE=$(ls -1 | grep MY_CSV_FILE.csv)
NAME=${FILE%%.csv}

head -1 $FILE > header.csv
tail -n +2 $FILE > data.csv

split -l 50 data.csv

for a in x??
    do
        cat header.csv $a > $NAME.$a.csv
    done

rm header.csv data.csv x??

Questo script dividerà MY_CSV_FILE.csv in nuovi file con un massimo di 50 linee durante la copia nell'intestazione originale nella parte superiore di ogni file. I nuovi file avranno il nome originale aggiunto con xaa , xab , xac ecc.

Per quanto riguarda la configurazione di Automator, questo è il servizio al quale sto attualmente lavorando. Il problema adesso è che non riesco a passare il file selezionato nel Finder allo script Bash.

Tienipresenteche:

  • Ilservizioriceve:fileocartelleinFinder.app.
  • Passal'inputalloscriptShell:comeargomenti.
  • Horimosso#!/bin/bashdallapartesuperiorediShellScriptehoimpostatolashellsu/bin/bash.
  • HocambiatoMY_CSV_FILE.csvper"$f" - non sono sicuro che sia corretto.

Devo anche specificare il percorso usando qualcosa come "$@" sia per il file di input che per i file di output risultanti? Non ho mai fatto qualcosa di simile prima, quindi non ho molta familiarità con quella variabile e "$f" per quella materia.

Come potrei fare questo lavoro? Mi piacerebbe che i file risultanti comparissero nella stessa cartella del file che seleziono per eseguire il servizio, tramite il menu del tasto destro del Finder. Sarebbe ancora meglio se il Servizio accettasse solo file CSV.

    
posta Winterflags 09.08.2017 - 15:37
fonte

1 risposta

6

Scriverò il codice in modo un po 'diverso, ed ecco un esempio di come lo farei io:

#!/bin/bash

for f in "$@"; do
    if [[ -f $f ]]; then
        d="$(dirname "$f")"
        n="$(basename "$f")"
        t='/tmp'
        if [[ ${n##*.} =~ [cC][sS][vV] ]]; then
            head -1 "$f" > $t/h.tmp
            tail -n +2 "$f" | split -a 3 -l 50 - $t/tmp.
            i=1
            for s in $t/tmp.a??; do
                fn="$d/${n%.*}.$(printf '%03d' $i).csv"
                if [[ ! -f $fn ]]; then 
                    cat $t/h.tmp $s > "$fn"
                    ((i++))
                else
                    rm $t/h.tmp $t/tmp.a??
                    echo "The file '"$fn"' already exists!"
                    exit
                fi
            done
            rm $t/h.tmp $t/tmp.a??
            echo ''
        fi
    fi
done
  • Come attualmente codificato, gestisce uno o più file passati al servizio .
  • Verifica che l'oggetto oggetto sia un file , non una directory .
  • Verifica che il file abbia un'estensione .csv (indipendentemente dal caso dell'estensione).
  • Crea i file temporanei in: /tmp
  • Controlla che il nome file di output non esista già e, in caso affermativo, pulisce ed esce.
  • Scrive su un file con un nome incrementale numerico , ad es. file.001.csv , file.002.csv , ecc., nella stessa directory poiché i file (s) sono passati al servizio .
  • Rimuove i file temporanei creati in: /tmp
  • Come attualmente codificato, gestisce file con un numero di righe di fino a 49.950 divisi in 50 file di linea, senza contare l'intestazione.
    • Si noti che nessuna gestione degli errori è codificata per il conteggio totale delle righe del file sorgente , tuttavia, potrebbe essere facilmente aggiunta.
    • O facilmente modificato per gestire file con un numero di righe di 499,950 divisi in 50 file di linea, senza contare l'intestazione, cambiando -a 3 della split comando a -a 4 e '%03d' del printf comando a '%04d' . Dovresti anche cambiare $t/tmp.a?? in
      for s in $t/tmp.a??; do e rm $t/h.tmp $t/tmp.a?? a: $t/tmp.a???

Inoltre, aggiungerei Esegui Apple Script azione al servizio , con il seguente codice :

on run {input, parameters}
    if (item 1 of input) is "" then
        display notification "Splitting of the target file(s) is finished!" with title "Split CSV File(s)"
    else
        display notification (item 1 of input as string) with title "Split CSV File(s)"
    end if
end run

Abilita l' output dei comandi echo nello Esegui script shell azione per visualizzare un notifica se esiste già un file di output o quando la divisione è terminata.

Si noti che mentre la notifica poteva essere eseguita all'interno dello Esegui script shell azione utilizzando osascript , tuttavia, l'ho fatto in questo modo poiché era più semplice codificarlo.

Questoèstatotestatosuunfiledenominatofile.csvinFinder,checontiene200righeeleimmaginisottostantimostranocosaèstatocreatodallaparteEseguiscriptShellazionedelAutomatorservizioquandovieneeseguitosulfile.

    
risposta data 12.08.2017 - 05:02
fonte

Leggi altre domande sui tag