Ich versuche, einen Automator- Dienst für das Rechtsklick-Kontextmenü von Finder zu erstellen, der jede ausgewählte CSV-Datei aufteilen kann, während der ursprüngliche Header oben in jeder Datei kopiert wird.
Mein aktueller Versuch besteht darin, Automator dazu zu bringen, dieses Bash-Shell-Skript auszuführen :
#!/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??
Dieses Skript wird in neue Dateien mit maximal 50 Zeilen aufgeteilt MY_CSV_FILE.csv
, während der ursprüngliche Header am Anfang jeder Datei kopiert wird. An die neuen Dateien wird der ursprüngliche Name mit xaa
, xab
, xac
usw. angehängt.
In Bezug auf die Automator-Einrichtung ist dies der Dienst, an dem ich derzeit arbeite. Das Problem im Moment ist, dass ich die ausgewählte Datei im Finder nicht an das Bash-Skript übergeben kann.
Beachte das:
#!/bin/bash
oben aus dem Shell-Skript entfernt und die Shell auf: /bin/bash gesetzt .MY_CSV_FILE.csv
für "$f"
– nicht sicher, ob das richtig ist.Muss ich auch den Pfad mit so etwas wie "$@"
für die Eingabedatei und die resultierenden Ausgabedateien angeben? Ich habe so etwas noch nie gemacht, also bin ich mit dieser Variable nicht wirklich vertraut und "$f"
was das betrifft.
Wie könnte ich das zum Laufen bringen? Ich möchte, dass die resultierenden Dateien im selben Ordner erscheinen wie die Datei, die ich über das Finder-Rechtsklickmenü zum Ausführen des Dienstes auswähle. Noch besser wäre es, wenn der Dienst nur csv-Dateien akzeptieren würde.
Ich würde den Code etwas anders schreiben, und hier ist ein Beispiel dafür, wie ich es machen würde:
#!/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
/tmp
file.001.csv
, file.002.csv
usw., im selben Verzeichnis wie die an den Dienst übergebene (n) Datei(en) ./tmp
-a 3
der split
Befehl in -a 4
und '%03d'
der printf
Befehl in geändert wird '%04d'
. Sie würden auch $t/tmp.a??
in for s in $t/tmp.a??; do
und rm $t/h.tmp $t/tmp.a??
zu ändern:$t/tmp.a???
Ich würde dem Dienst auch eine Run Apple Script- Aktion mit dem folgenden Code hinzufügen :
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
Dadurch wird die Ausgabe der echo
Befehle in der Aktion Shell-Skript ausführen aktiviert , um eine Benachrichtigung anzuzeigen, wenn eine Ausgabedatei bereits vorhanden ist oder wenn die Teilung abgeschlossen ist.
Beachten Sie, dass die Benachrichtigung zwar innerhalb der Aktion „Run Shell Script“ mit ausgeführt werden konnte , ich es jedoch so gemacht habe, da es einfacher zu programmieren war.osascript
Dies wurde an einer Datei namens file.csv im Finder getestet , die 200 Zeilen enthält, und die Bilder unten zeigen, was durch den Aktionsteil „Run Shell Script“ des Automator-Dienstes erstellt wurde, wenn er auf der Datei ausgeführt wurde .
$a
, dh x??
, zB xaa
, xab
usw. Es ist eine persönliche Präferenz für mich, ich möchte einen numerischen Wert in den geteilten Dateinamen, also habe ich es dafür codiert . Im Code des OP for a in x??
wäre es fehlgeschlagen, wenn die Quelldatei eine Zeilenzahl von mehr als 49.950 hätte, die in Dateien mit 50 Zeilen aufgeteilt wäre, da x??
nur 999 Dateien berücksichtigt werden, wo x???
9999 Dateien berücksichtigt werden.split
ohne Platz zu bieten zuerst die Berechnungen durchführen oder die Berechnungen können zuerst durchgeführt und so codiert werden, dass sie sich dynamisch anpassen. Es ist weniger Codierung, um das Pad anzupassen, als zuerst die Zeilenanzahl zu überprüfen. Wenn Sie eine sehr hohe Anzahl von Zeilen sicherstellen möchten, erhöhen Sie die Werte noch höher als in meiner Antwort angegeben, damit das Pad mehr als ausreichend ist.-a 3
des split
Befehls zu -a 5
und '%03d'
des printf
Befehls zu '%04d'
und $t/tmp.a??
in for s in $t/tmp.a??; do
und rm $t/h.tmp $t/tmp.a??
zu $t/tmp.a????
, verarbeitet Dateien mit einer Zeilenzahl von bis zu 4.999.950, aufgeteilt auf 50 Zeilendateien. Um es noch einfacher zu machen, $t/tmp.a??
kann eingestellt werden $t/tmp.*
und dann müssten Sie nur -a 3
den split
Befehl und '%03d'
die printf
Befehlseinstellung jeweils auf eine höhere Zahl ändern, zB -a 8
und '%08d'
werden Dateien mit einer Zeilenzahl von bis zu 4.999.999.950 auf 50 Zeilen aufgeteilt Dateien.
Monomet
PFANNE
x??.csv
Es scheint auch eine Datei namens in meinem Benutzerordner ( ) erstellt zu haben~
.