파이톤으로 조개 스크립트를 다시 썼어요.
개요
나는 일을 더욱 수월하게 하기 위해 개인적으로 조개 각본을 썼다.
나는 이것을 다른 구성원들과 공유하여 팀 전체의 업무 효율을 향상시키고 개선하고 싶다.
하지만 조개 스크립트를 접한 멤버가 적어 접한 파이톤으로 다시 쓰기로 했다.(무슨 시험 문제의 도입문인 것 같다)
어떤 조개 스크립트일까요?
케이스 스크립트는 여기 기사.의 템플릿을 참조했습니다.
처리 내용은 대략 다섯 개다.
조개 스크립트는 대충 이런 느낌
#!/usr/bin/env bash
set -Eeuo pipefail
trap cleanup SIGINT SIGTERM ERR EXIT
script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P)
usage() {
cat <<EOF
Usage:
bash $(basename "${BASH_SOURCE[0]}") [-h] [-v] [-ot] [-op] [-r aftername] dirname
# これは何?
hoge用のシェルスクリプトです。
dirnameに作業ディレクトリ名を入力してください。
ディレクトリ構成は以下です。
-------------------------------
./
├── cli.sh
└── template
├── A.tex
├── QandA.tex
└── Q.tex
-------------------------------
# 使い方
"bash cli.sh hoge"とコマンドラインに入力することで、
カレントディレクトリにhogeという作業ディレクトリが作成されます。
構成は以下です。
-------------------------------
hoge
├── hoge_Q.tex ... 問題texファイル
├── hoge_A.tex ... 解答texファイル
└── hoge.tex ... 問題と解答を1つにするtexファイル
-------------------------------
また、"bash cli.sh fuga/hoge"とコマンドラインに入力することで、
カレントディレクトリにfugaというディレクトリが作成され、
fugaの中にhogeという作業ディレクトリが作成されます。
構成は以下です。
-------------------------------
hoge
├── hoge_Q.tex ... texファイル1
├── hoge_A.tex ... texファイル2
└── hoge.tex ... 上記2つを1つにするtexファイル
-------------------------------
# オプション一覧
-h, --help ヘルプを表示
-v, --verbose デバッグ用なので気にしないで
-ot, --opentex エディタでTeXファイルを開く
-op, --openpdf 出力PDFファイルを開く
-c, --clear コンパイルで作られた一時ファイルを削除
-r, --rename 間違えたとき用に一括置換
EOF
exit
}
cleanup() {
trap - SIGINT SIGTERM ERR EXIT
}
setup_colors() {
if [[ -t 2 ]] && [[ -z "${NO_COLOR-}" ]] && [[ "${TERM-}" != "dumb" ]]; then
NOFORMAT='\033[0m' RED='\033[0;31m' GREEN='\033[0;32m' ORANGE='\033[0;33m' BLUE='\033[0;34m' PURPLE='\033[0;35m' CYAN='\033[0;36m' YELLOW='\033[1;33m'
else
NOFORMAT='' RED='' GREEN='' ORANGE='' BLUE='' PURPLE='' CYAN='' YELLOW=''
fi
}
msg() {
echo >&2 -e "${1-}"
}
die() {
local msg=$1
local code=${2-1}
msg "$msg"
exit "$code"
}
parse_params() {
opentex=0
openpdf=0
rename=''
clearfiles=0
while :; do
case "${1-}" in
-h | --help) usage ;;
-v | --verbose) set -x ;;
--no-color) NO_COLOR=1 ;;
-ot | --opentex) opentex=1 ;;
-op | --openpdf) openpdf=1 ;;
-c | --clear) clearfiles=1 ;;
-r | --rename)
rename="${2-}"
shift
;;
-?*) die "Unknown option: $1" ;;
*) break ;;
esac
shift
done
args=("$@")
[[ ${#args[@]} -eq 0 ]] && die "作業ディレクトリを指定してください。"
return 0
}
parse_params "$@"
setup_colors
# ----------------------------------------------------------------
dirname=${args[0]}
filename=${dirname##*/}
if [[ -n $rename ]]; then
if [[ ! -d $dirname ]]; then
die "「$dirname」が存在しません。"
fi
echo -n "$dirnameから$renameへ一括置換をしますか? (y/n) >"
read do_rename
if [[ $do_rename = 'y' ]]; then
sed -i s/$dirname/$rename/g $dirname/$filename.tex
mkdir $rename
mv $dirname/$filename.tex $rename/$rename.tex
mv $dirname/${filename}_Q.tex $rename/${rename}_Q.tex
mv $dirname/${filename}_A.tex $rename/${rename}_A.tex
rmdir $dirname
echo "$dirnameから$renameへ一括置換しました"
else
echo "一括置換は行われませんでした"
fi
exit 0
fi
if [[ ! -d $dirname ]]; then
mkdir $dirname
cp template/QandA.tex $dirname/$filename.tex
cp template/Q.tex $dirname/${filename}_Q.tex
cp template/A.tex $dirname/${filename}_A.tex
sed -i s/DIRNAME/$filename/g $dirname/$filename.tex
fi
pdf=$dirname/$filename.pdf
if [[ $openpdf = 1 ]]; then
if [[ -f $pdf ]]; then
/mnt/c/Program\ Files/SumatraPDF/SumatraPDF.exe $pdf &
else
/mnt/c/Program\ Files/SumatraPDF/SumatraPDF.exe &
fi
fi
if [[ $clearfiles = 1 ]]; then
rm $dirname/*.aux $dirname/*.dvi $dirname/*.fdb_latexmk $dirname/*.fls $dirname/*.log $dirname/*.synctex.gz
fi
if [[ $opentex = 1 ]]; then
cd $dirname
vim *.tex
fi
내 환경은 Ubuntu(WSL2)이기 때문에 텍스트 편집기와 PDF의 시청자 부분은 각자 다시 쓰십시오.이외의 섹션 = 파일 작업은 Windows와 Ubuntu를 막론하고 향상됩니다.또한 파이썬은 표준 라이브러리만 사용합니다.고쳐 쓰다
매개변수 및 도움말
조개 스크립트는 이렇게 매개 변수를 처리한다
while
.조개각본
opentex=0
openpdf=0
rename=''
clearfiles=0
while :; do
case "${1-}" in
-h | --help) usage ;;
-v | --verbose) set -x ;;
--no-color) NO_COLOR=1 ;;
-ot | --opentex) opentex=1 ;;
-op | --openpdf) openpdf=1 ;;
-c | --clear) clearfiles=1 ;;
-r | --rename)
rename="${2-}"
shift
;;
-?*) die "Unknown option: $1" ;;
*) break ;;
esac
shift
done
args=("$@")
[[ ${#args[@]} -eq 0 ]] && die "作業ディレクトリを指定してください。"
또한 도움말의 내용은 usage
이라는 함수에 쓰여 있다.조개각본
usage() {
cat <<EOF
Usage:
bash $(basename "${BASH_SOURCE[0]}") [-h] [-v] [-ot] [-op] [-r aftername] dirname
# これは何?
省略
# 詳しい使い方
省略
# オプション一覧
-h, --help ヘルプを表示
省略
EOF
exit
}
Python으로 이것을 다시 쓰려면 argparse 모듈 을 사용하십시오.Python
import argparse
p = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description="""
# これは何?
省略
# 詳しい使い方
省略
""",
)
# 位置引数
p.add_argument("dirname", help="作業ディレクトリ名")
# オプション引数
group = p.add_mutually_exclusive_group()
group.add_argument("-ot", "--opentex", help="エディタでTeXファイルを開く", action="store_true")
group.add_argument("-op", "--openpdf", help="出力PDFファイルを開く", action="store_true")
group.add_argument("-c", "--clear", help="コンパイルで作られた一時ファイルを削除", action="store_true")
group.add_argument("-r", "--rename", help="間違えたとき用に一括置換")
args = p.parse_args()
ArgumentParser 대상을 만들고 add_argument 방법으로 파라미터를 추가합니다.매개 변수의 값은 parse_args
에서 args.dirname
, args.opentex
등으로 되돌아갈 수 있다.자기가
--help
옵션을 추가하지 않아도 add_argument
방법help
으로 usage와 옵션을 잘 표시할 수 있습니다.usage: cli.py [-h] [-ot | -op | -c | -r RENAME] dirname
positional arguments:
dirname 作業ディレクトリ名
optional arguments:
-h, --help show this help message and exit
-ot, --opentex エディタでTeXファイルを開く
-op, --openpdf 出力PDFファイルを開く
-c, --clear コンパイルで作られた一時ファイルを削除
-r RENAME, --rename RENAME
間違えたとき用に一括置換
이번에는 description도 지정했다.도움말의 usage와positional arguments 사이에 description
지정한 내용을 추가합니다.description
에서 줄을 원상태로 바꾸기 위해formatter_class에서 RawDescriptionHelpFormatter
를 지정했습니다.add_argument
방법에서 머리에 -
를 첨가한 후 선택할 수 있는 매개 변수이고 첨가하지 않으면 위치 매개 변수이다.이 설정action="store_true"
에서 매개변수가 지정되면 True를 사용할 수 있고 그렇지 않으면 False를 사용할 수 있습니다.ArgumentParser
의 대상에서 add_mutually_exclusive_group
방법을 사용하면 조합 내의 매개 변수를 2개 이상 동시에 사용할 수 없다.usage에도 그걸 반영했네요.그리고
if args.opentex:
pass
처럼 조건에 따라 띄어쓰기만 하면 된다.파일 작업
Unix든 Windows든
os
모듈을 사용하여 처리 경로를 적절히 만들 수 있습니다.바쁜 사람을 위해 자주 쓰는 것들을 나열하다.
os.sep: 경로 구분자 가져오기
os.path.join: 경로의 결합
os.path.split: 패스의 끝 및 이전 분할
os.path.exists: 경로가 실제로 존재하는지 여부
os.rename: 이름 바꾸기
os.mkdir: 디렉토리 만들기
os.remove: 삭제
기억하기 쉬운데.
서류의 복사본은 shutil.copyfile(src, dist)처럼
shutil
모듈을 사용했다(이것만 갑자기 머릿속에 나타나지 않았다).편집기 시작 등
subprocess 모듈을 사용하여 텍스트 편집기와 PDF 관찰기를 시작합니다.
Python
import subprocess as sb
if args.opentex:
sb.run("cd {} && vim *.tex".format(dirname), shell=True)
원래 첫 번째 파라미터에 명령과 파라미터의 목록을 지정하였으나 문자열로 직접 쓰려고 지정하였습니다shell=True
.출력을 변경할 때는 stdout
또는 stderr
로 지정할 수 있습니다.완성품
그래서 완제품은 여기에 있다
import argparse
import os
import re
import sys
import shutil
import subprocess as sb
p = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description="""
# これは何?
dirnameに作業ディレクトリ名を入力してください。
ディレクトリ構成は以下です。
-------------------------------
./
├── cli.py
└── template
├── A.tex
├── QandA.tex
└── Q.tex
-------------------------------
# 使い方
## 主な使い方
"python cli.py hoge"とコマンドラインに入力することで、
カレントディレクトリにhogeという作業ディレクトリが作成されます。
構成は以下です。
-------------------------------
hoge
├── hoge_Q.tex ... 問題texファイル
├── hoge_A.tex ... 解答texファイル
└── hoge.tex ... 問題と解答を1つにするtexファイル
-------------------------------
また、"python cli.py fuga/hoge"とコマンドラインに入力することで、
カレントディレクトリにfugaというディレクトリが作成され、
fugaの中にhogeという作業ディレクトリが作成されます。
構成は以下です。
-------------------------------
hoge
├── hoge_Q.tex ... 問題texファイル
├── hoge_A.tex ... 解答texファイル
└── hoge.tex ... 問題と解答を1つにするtexファイル
-------------------------------
以下省略
""",
)
# 位置引数
p.add_argument("dirname", help="作業ディレクトリ名")
# オプション引数
group = p.add_mutually_exclusive_group()
group.add_argument("-ot", "--opentex", help="エディタでTeXファイルを開く", action="store_true")
group.add_argument("-op", "--openpdf", help="出力PDFファイルを開く", action="store_true")
group.add_argument("-c", "--clear", help="コンパイルで作られた一時ファイルを削除", action="store_true")
group.add_argument("-r", "--rename", help="間違えたとき用に一括置換")
args = p.parse_args()
# hoge でも hoge/fuga でも hoge/ でも hoge/fuga/ でも対応 windowsでも対応
dirname = re.sub(repr(os.sep + "$")[1:-1], "", args.dirname)
filename = os.path.split(dirname)[-1]
dir_file_name = os.path.join(dirname, filename)
# 一括置換
if args.rename:
re_dirname = re.sub(repr(os.sep + "$")[1:-1], "", args.rename)
re_filename = os.path.split(re_dirname)[-1]
# ファイルチェック
if not os.path.exists(dirname):
print("「{}」が存在しません".format(dirname), file=sys.stderr)
sys.exit(1)
if os.path.exists(re_dirname):
print("「{}」は既に存在しています".format(re_dirname), file=sys.stderr)
sys.exit(1)
do_rename = input("{}から{}へ一括置換をしますか? (y/n) >".format(dirname, re_dirname))
if do_rename == "y":
# ファイル内の文字列を置換
with open(dir_file_name + ".tex") as f:
lines = f.read()
lines = lines.replace(filename, re_filename)
with open(dir_file_name + ".tex", mode="w") as f:
f.write(lines)
# ファイル名のリネーム
os.rename(dirname, re_dirname)
for qa in ["", "_Q", "_A"]:
os.rename(
os.path.join(re_dirname, filename + qa + ".tex"),
os.path.join(re_dirname, re_filename + qa + ".tex"),
)
print("{}から{}へ一括置換しました".format(dirname, re_dirname))
sys.exit(0)
else:
print("一括置換は行われませんでした")
sys.exit(0)
# テンプレートのコピー
if not os.path.exists(dirname):
os.mkdir(dirname)
# テンプレ文字列を置換
with open(os.path.join("template", "QandA.tex")) as f:
lines = f.read()
lines = lines.replace("DIRNAME", filename)
# テンプレをコピー
with open(dir_file_name + ".tex", mode="w") as f:
f.write(lines)
shutil.copyfile(os.path.join("template", "Q.tex"), dir_file_name + "_Q.tex")
shutil.copyfile(os.path.join("template", "A.tex"), dir_file_name + "_A.tex")
if args.openpdf:
pdf = os.path.join(dirname, filename + ".pdf")
if os.path.exists(pdf):
sb.run(
"/mnt/c/Program\ Files/SumatraPDF/SumatraPDF.exe {} &".format(pdf),
stdout=sb.DEVNULL,
stderr=sb.DEVNULL,
shell=True,
)
else:
sb.run(
"/mnt/c/Program\ Files/SumatraPDF/SumatraPDF.exe & ",
shell=True,
)
if args.clear:
for rf in [".aux", ".dvi", ".fdb_latexmk", ".fls", ".log", ".synctex.gz"]:
os.remove(dir_file_name + rf)
if args.opentex:
sb.run("cd {} && vim *.tex".format(dirname), shell=True)
파이톤에 익숙해서 쓰기가 편해요.매개 변수의 해석과 도움말을 함께 쓰기 때문에 usage와 옵션의 표시도 마음대로 쉽게 할 수 있습니다.argparse
에도 자습서가 있다.
Reference
이 문제에 관하여(파이톤으로 조개 스크립트를 다시 썼어요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/eetann/articles/2021-02-21-shellscript2python텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)