Convert command line arguments to list in Emacs Lisp
command-line, command-line-arguments, elisp, emacs
Solution
You can use `split-string`. See the following code example.
(setq cmd-line '("--aaa=bbb" "--ccc=ddd=eee" "--blah"))
(setq cmd-line (mapcar (lambda (argstr)
(when (string-match "^--" argstr)
(split-string (substring argstr 2) "=")))
cmd-line))
The output is `(("aaa" "bbb") ("ccc" "ddd" "eee") ("blah"))`. That is not exactly what you want because of `"eee"`. Maybe you can use that and just neglect `"eee"`.
If the `"eee"` is really a problem a small modification helps:
(setq cmd-line '("--aaa=bbb" "--ccc=ddd=eee" "--blah"))
(setq cmd-line (mapcar (lambda (arg)
(when (string-match "^--" arg)
(setq arg (split-string (substring arg 2) "="))
(if (cdr arg)
(setcdr (cdr arg) nil))
arg))
cmd-line))
The output is:
(("aaa" "bbb") ("ccc" "ddd") ("blah"))
Variant for the new requirement in the question:
(setq cmd-line '("--aaa=bbb" "--ccc=ddd=eee" "--blah"))
(setq cmd-line (mapcar (lambda (arg)
(when (string-match "^--\\([^=]*\\)\\(?:=\\(.*\\)\\)?" arg)
(let ((opt (match-string 1 arg))
(val (match-string 2 arg)))
(if val
(list opt val)
(list opt)))))
cmd-line))
The output is:
(("aaa" "bbb") ("ccc" "ddd=eee") ("blah"))
Problem
In an automated Emacs Lisp `--batch/--script` script I need to process the command line arguments given to the script. I've gotten as far as getting the arguments into a list of the the form: ``` ("--aaa=bbb" "--ccc=ddd=eee" "--blah") ``` Now, I need to convert them to a list of the form: ``` (("aaa" "bbb") ("ccc" "ddd=eee") ("blah")) ``` In Python I'd write something like; ``` output = [] for v in input: output.append(v[2:].split("=", 1)) ``` But have been unable to convert that code to Emacs Lisp. I found Elisp split-string function to split a string by . character but wasn't able to figure out how to make it only split on the first equals. I was heading down a route of using `(substring "abcdefg" x x)` with `(search)` from the `cl` package but it felt like there should be a better way? I think also want to use `(mapc '<function> input)` where function does the `v[2:].split("=",1)` part.