There are two considerations here: 1) write a function to extract the needed information and 2) run the function on an Org mode file from the command line. The two are pretty much orthogonal, so you should start with a simple function that extracts some useful information (but not necessarily all that you indicate above) and figure out how to run it from the command line. Once you have debugged that and can see your way through the forest, then write a more complicated function for step 1) that incrementally gets you to where you eventually want to go.
For example, suppose that we want to do the equivalent of wc -l: print the number of lines in the file. That's a much simpler function that doesn't even involve Org mode; nevertheless, it provides you an opportunity to figure out the mechanics of calling it on a file from the command line.
Here's a simple function that gives you the number of lines in the current buffer:
(defun ndk/count-lines () (save-excursion (goto-char (point-max)) (1- (line-number-at-pos))))
You should run this function with M:- (ndk/count-lines) in various files to make sure it works as expected. Compare its output with that of wc -l.
Now to run this function on a file from the command line, store it in a file (let's call the file minimal-init.el and put it in the current directory for simplicity). Then to run the function on a file and print the result to stdout, run this command line:
emacs --batch --load ./minimal-init.el --file foo.org --eval '(print (ndk/count-lines))`
Explanation:
We run a batch session: that means that your init file is skipped, there is no interaction, there is no graphical frame opened and the standard functions print and message modify their behavior to produce output on stdout and stderr respectively (since there is no visible bufer or echo area for them to use). In addition, when all the arguments have been processed, emacs exits.
We then load a minimal init file that contains the definition of the function(s) that we eventually want to run (and any functions that they depend on that are user-defined).
Then we open the file foo.org which creates a buffer, but the buffer is not shown since there is no frame to show it. Nevertheless, that becomes the current buffer.
Finally we evaluate the expression: the function to count lines in the current buffer is called, it returns the number of lines as its result and then print prints that result (to stdout). After that, emacs exits.
That's step 1 - you can now use a different function to print some other information about the file. For example, try the following:
(defun ndk/org-heading-list () "Map the `ndk/heading' function on all entries of the current buffer." (org-map-entries #'ndk/heading t 'file)) (defun ndk/heading () "Return the text of the heading of the current entry." (org-get-heading t t t t))
Put these functions into your ./minimal-init.el file and run the same command line, except for replacing the ndk/count-lines function with ndk/org-heading-list:
emacs --batch --load ./minimal-init.el --file foo.org --eval '(print (ndk/org-heading-list))`
For your simple example file (from your linked question), I get:
$ emacs --batch --load ./minimal-init.el --file foo.org --eval '(print (ndk/org-heading-list))' ("Example" "foo" "subheading" "bar" "subheading") $
Now you can write a more complicated function to act on the current bufffer that does what you really want to do and add it to your ./minimal-init.el, but the invocation will be identical except for the name of that function.
And given that this answers the question in your title even though it does not answer the (more complicated) question in your comment, if you have problems writing that function, you should ask a different question on that.
emacsto parse Org mode files from the command line?emacs --batch -l org --eval '( ??? )')?