Dividir archivo csv usando el Servicio Automator (Menú contextual del Finder)

2

Estoy tratando de crear un Automator Service para el Finder del menú contextual del botón derecho que puede dividir cualquier archivo csv seleccionado, mientras copiando en el encabezado original en la parte superior de cada archivo.

Mi intento actual es hacer que Automator ejecute esta secuencia de comandos 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??

Este script dividirá MY_CSV_FILE.csv en archivos nuevos con un máximo de 50 líneas mientras se copia en el encabezado original en la parte superior de cada archivo. Los nuevos archivos tendrán el nombre original adjunto con xaa , xab , xac etc.

Con respecto a la configuración de Automator, este es el servicio en el que estoy trabajando actualmente. El problema ahora es que no puedo pasar el archivo seleccionado en Finder al script Bash.

Noteque:

  • Elserviciorecibe:archivosocarpetasenFinder.app.
  • PaselaentradaalscriptdeShell:comoargumentos.
  • Heeliminado#!/bin/bashdelapartesuperiordelasecuenciadecomandosdeShellylaheconfiguradocomo:/bin/bash.
  • CambiéMY_CSV_FILE.csvpor"$f" . No estoy seguro de si eso es correcto.

¿También debo especificar la ruta usando algo como "$@" tanto para el archivo de entrada como para los archivos de salida resultantes? No he hecho algo como esto antes, así que no estoy realmente familiarizado con esa variable y "$f" para esa materia.

¿Cómo podría hacer que esto funcione? Me gustaría que los archivos resultantes aparezcan en la misma carpeta que el archivo que seleccioné para ejecutar el Servicio, mediante el menú de clic derecho del Buscador. Sería aún mejor si el Servicio solo aceptara archivos csv.

    
pregunta Winterflags 09.08.2017 - 15:37

1 respuesta

6

Escribiría el código un poco diferente, y aquí hay un ejemplo de cómo lo haría:

#!/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
  • Como está codificado actualmente, maneja uno o más archivos pasados al servicio .
  • Se asegura de que se actúe sobre objeto en un archivo , no en un directorio .
  • Se asegura de que el archivo tenga una extensión .csv (independientemente del caso de la extensión).
  • Crea los archivos temporales en: /tmp
  • Comprueba que el nombre de archivo de salida ya no existe, y si lo hace, se limpia y sale.
  • Escribe en un archivo con un nombre de archivo incrementado numéricamente , por ejemplo. file.001.csv , file.002.csv , etc., en el mismo directorio que archivo (s) se pasó al servicio .
  • Elimina los archivos temporales creados en: /tmp
  • Como está codificado actualmente, maneja archivos con un line count de hasta 49,950 divididos en 50 archivos de línea, sin contar el encabezado.
    • Tenga en cuenta que no se codifica el manejo de errores para el recuento total de líneas del archivo fuente , sin embargo, podría agregarse fácilmente.
    • O se modifica fácilmente para manejar archivos con line count de hasta 499,950 divididos en 50 archivos de línea, sin contar el encabezado, cambiando -a 3 of split comando a -a 4 y '%03d' del printf comando a '%04d' . También cambiarías $t/tmp.a?? en
      for s in $t/tmp.a??; do y rm $t/h.tmp $t/tmp.a?? a: $t/tmp.a???

También agregaría una Ejecutar Apple Script acción al servicio , con el siguiente código :

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

Esto permite que la salida de los comandos echo en Ejecutar script de shell acción muestre una notificación si ya existe un archivo de salida o cuando finaliza la división.

Tenga en cuenta que si bien la notificación se puede hacer desde Ejecutar script de shell acción utilizando osascript , no obstante, lo hice de esta manera porque era más fácil de codificar.

Estoseprobóenunarchivollamadofile.csvenFinder,quetiene200líneas,ylasimágenesacontinuaciónmuestranquéfuecreadoporlaparteEjecutarelscriptdeshellaccióndelAutomatorserviciocuandoseejecutaenelarchivo.

    
respondido por el user3439894 12.08.2017 - 05:02

Lea otras preguntas en las etiquetas