(...I figured out how to post tab character in sample TSV text in the source code. It cannot be posted directly...)
Hello
If you want to implement unattended background process, here's an AppleScript script you may explore. I think the code is fairly self-explanatory with embedded comments. You may specify the POSIX path of the Numbers file in |FILE|, sheet index or name in |SHEET| and table index or name in |TABLE| properties in script.
When it is run, it will open the specified file if not yet open, populate the table, save and close the document if it is opened by the script. (If the file is already open when it is run, script will not close it. Also if script opens the file, it will minimize the window before processing the file.)
--APPLESCRIPT
on run
set tsv to "value_11" & tab & "value_12" & tab & "value_13" & linefeed & ¬
"value_21" & tab & "value_22" & tab & "value_23" & linefeed & ¬
"value_31" & tab & "value_32" & tab & "value_33" & tab & "value_34" & linefeed
_main(tsv)
end run
on _main(argv)
(*
string argv : TSV text
*)
script o
property |FILE| : (path to home folder)'s POSIX path & "Desktop/a.numbers"
property |SHEET| : 1 -- index or name
property |TABLE| : 1 -- index or name
property aa : _text2array(argv, tab, linefeed) -- 2d-array from TSV text
set |FILE| to (|FILE| as POSIX file as alias)'s POSIX path -- normalise the path (optional)
tell application "Numbers"
tell (document 1 whose path = |FILE|)
set _was_open to exists
if not _was_open then -- open the file if not yet open
open |FILE| as POSIX file
repeat until exists
tell current application to delay 0.5
end repeat
end if
set doc to it
end tell
if not _was_open then
tell (window 1 where its document = doc)
set miniaturized to true -- minimise the window (optional)
end tell
end if
tell doc
tell sheet |SHEET|'s table |TABLE|
set jx to count columns
repeat with i from 1 to count my aa
set a to my aa's item i
if (count a) = 0 then -- ignore empty record
else
add row below row -1 -- add new row at end
tell row -1
repeat with j from 1 to count a
if j > jx then
add column after cell -1 -- add column if necessary
set jx to jx + 1
end if
set cell j's value to a's item j
end repeat
end tell
end if
end repeat
end tell
if modified then save -- save changes
if not _was_open then close -- close the file if not originally open
end tell
end tell
end script
tell o to run
end _main
on _text2array(t, fs, rs)
(*
string t : source text
string fs : column separator (field separator)
string rs : row separator (record separator)
return list : 2d-array represented by t
*)
script o
property pp : _split(t, rs)
property qq : {}
repeat with p in my pp
set end of my qq to _split(p's contents, fs)
end repeat
return my qq's contents
end script
tell o to run
end _text2array
on _split(t, d)
(*
string t : source string
string or list d : separator(s)
return list : t splitted by d
*)
local astid0, tt
try
set {astid0, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {} & d}
set tt to t's text items
set AppleScript's text item delimiters to astid0
on error errs number errn
set AppleScript's text item delimiters to astid0
error errs number errn
end try
return tt
end _split
--END OF APPLESCRIPT
If you want to use it in Automator's Run AppleScript action, you need to change the run handler to the following:
on run {input, parameters}
_main(input's item 1)
end run
and receive tsv text from previous action.
---
And now that you mentioned perl, here's perl script to invoke the applescript via osascript(1).
#!/usr/bin/perl -w
use strict;
my $tsv = <<"TSV";
value_11\tvalue_12\tvalue_13
value_21\tvalue_22\tvalue_23
value_31\tvalue_32\tvalue_33\tvalue_34
TSV
system('/usr/bin/osascript', '-e', &applescript(), $tsv) == 0
or die "applescript failed: $?";
sub applescript() {
return <<'APPLESCRIPT'
on run argv
_main(argv's item 1)
end run
on _main(argv)
(*
string argv : TSV text
*)
script o
property |FILE| : (path to home folder)'s POSIX path & "Desktop/a.numbers"
property |SHEET| : 1 -- index or name
property |TABLE| : 1 -- index or name
property aa : _text2array(argv, tab, linefeed) -- 2d-array from TSV text
set |FILE| to (|FILE| as POSIX file as alias)'s POSIX path -- normalise the path (optional)
tell application "Numbers"
tell (document 1 whose path = |FILE|)
set _was_open to exists
if not _was_open then -- open the file if not yet open
open |FILE| as POSIX file
repeat until exists
tell current application to delay 0.5
end repeat
end if
set doc to it
end tell
if not _was_open then
tell (window 1 where its document = doc)
set miniaturized to true -- minimise the window (optional)
end tell
end if
tell doc
tell sheet |SHEET|'s table |TABLE|
set jx to count columns
repeat with i from 1 to count my aa
set a to my aa's item i
if (count a) = 0 then -- ignore empty record
else
add row below row -1 -- add new row at end
tell row -1
repeat with j from 1 to count a
if j > jx then
add column after cell -1 -- add column if necessary
set jx to jx + 1
end if
set cell j's value to a's item j
end repeat
end tell
end if
end repeat
end tell
if modified then save -- save changes
if not _was_open then close -- close the file if not originally open
end tell
end tell
end script
tell o to run
end _main
on _text2array(t, fs, rs)
(*
string t : source text
string fs : column separator (field separator)
string rs : row separator (record separator)
return list : 2d-array represented by t
*)
script o
property pp : _split(t, rs)
property qq : {}
repeat with p in my pp
set end of my qq to _split(p's contents, fs)
end repeat
return my qq's contents
end script
tell o to run
end _text2array
on _split(t, d)
(*
string t : source string
string or list d : separator(s)
return list : t splitted by d
*)
local astid0, tt
try
set {astid0, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {} & d}
set tt to t's text items
set AppleScript's text item delimiters to astid0
on error errs number errn
set AppleScript's text item delimiters to astid0
error errs number errn
end try
return tt
end _split
APPLESCRIPT
}
Tested with Numbers v2.0.5 under OS X 10.6.8.
Good luck,
H