~/bin/align-tables
emacs stackexchange에서 이 스크립트를 얻었습니다.
#!/bin/sh
# -*- mode: shell-script -*-
#
# tangle files with org-mode
#
DIR=`pwd`
FILES=""
# wrap each argument in the code required to call tangle on it
for i in $@; do
FILES="$FILES \"$i\""
done
emacs -Q --batch \
--eval "(progn
(require 'org)(require 'org-table)
(mapc (lambda (file)
(find-file (expand-file-name file \"$DIR\"))
(org-table-map-tables 'org-table-align)
(write-file file nil)
(kill-buffer)) '($FILES)))"
.org
이 스크립트를 디렉토리의 모든 파일 에 적용하고 싶습니다 ~/foo
. 내 작업 디렉토리가 /foo
다음이면 릴리스가 $ align-tables *.org
완벽하게 작동합니다. 그러나 다른 디렉토리에 있으면 $ align-tables ~/foo/*.org
오류가 발생합니다.
Opening output file: no such file or directory, ~/foo/foo/#bar.org#
오류 메시지에 대상 디렉터리가 두 번 나열되어 있으므로 스크립트의 해당 줄에 문제가 있다고 가정 DIR='pwd'
하지만 스크립트를 수정하는 방법을 잘 모르겠습니다.
align-tables
나의 동기는 다양한 디렉토리에서 작동하는 Perl 프로그램을 작성하고 있다는 것입니다 .
내 스크립트가 협력하도록 하는 방법에 대한 아이디어가 있습니까?
답변1
완전성을 기하기 위해 이 문제는 셸에서 순수하게 해결할 수 있습니다.
for i in "$@"; do
pushd "$(dirname "$i")"
DIR=`pwd`
FILES="\"$(basename "$i")\""
emacs -Q --batch \
--eval "(progn
(require 'org)(require 'org-table)
(mapc (lambda (file)
(find-file (expand-file-name file \"$DIR\"))
(org-table-map-tables 'org-table-align)
(write-file file nil)
(kill-buffer)) '($FILES)))"
popd
done
그러면 각 파일의 포함 디렉터리로 변경된 다음 emacs
상대 경로 이름을 사용하여 해당 단일 파일에 대해 기존 명령을 실행한 다음 다시 전환합니다.
이는 비효율적이며 잘못될 수 있는 일이 많습니다(특히 elisp를 삽입할 때 문제를 일으킬 수 있는 이상한 경로 이름*). 그리고 확실히 emacs 자체 내에 더 나은 솔루션이 있지만 원본 스크립트만큼 잘 작동합니다.
* 예를 들어 다음과 같은 파일이 있다고 가정합니다.
"
따옴표는 문자 그대로 포함되고 닫는 문자열 리터럴로 처리되므로 elisp 스크립트에서 구문 오류가 발생합니다. 다른 사람이 존재하는 파일 이름을 제어할 수 있다면 임의의 코드를 실행하는 코드를 생성할 수 있지만 해당 파일 이름이 없어도 문제가 발생할 수 있습니다.
답변2
\[?*"~
현재 디렉터리의 경로나 명령줄에 전달된 파일 이름에 특수 문자(공백, )가 포함되어 있으면 이 스크립트는 다양한 방식으로 실패합니다. 그러나 "길들인" 파일 이름의 경우 보기에는 좋아 보입니다(지나치게 복잡하지만 나쁘지는 않습니다).
#bar.org#
자동 저장 파일입니다. Emacs는 수정 시 연관된 버퍼를 생성하고 bar.org
, 버퍼를 저장할 때 삭제합니다.
파일 이름, 특히 그 부분에 무슨 일이 일어나고 있는지 잘 모르겠습니다 ~/foo/foo/
. 하지만 지어낸 이름으로는 진단하기가 어렵습니다. 해당 부분에 대한 도움이 필요하면 실제 파일 이름이 포함된 예제를 게시해 주세요. /tmp
사용자 이름이 공개되는 것을 원하지 않으시면 아래 파일을 드롭해 주세요.
문제는 Org 파일의 다른 파일에 대한 참조와 관련이 있을 수 있습니다. 내용을 보지 않고는 알기 어렵습니다. 도움이 필요하면 실제 파일 내용과 스크립트 실행의 전체 출력을 게시해 주세요.
명령줄에 전달된 모든 파일을 조작하는 더 쉬운 방법이 있습니다. 먼저 게시한 스크립트는 FILES
변수에 파일 이름이 포함된 일부 Emacs 코드를 빌드합니다. 하지만 이렇게 할 필요는 없습니다. emacs
명령줄에 파일 이름을 전달하고 argv
변수에서 사용하면 됩니다. 파일을 열 때 절대 파일 이름을 만들 필요가 없습니다. 이름을 find-file
.
#!/bin/sh
emacs --batch -l org -l org-table --eval "
(mapc (lambda (file)
(find-file (file))
(org-table-map-tables 'org-table-align)
(save-buffer)
(kill-buffer)
argv)
" "$@"