터미널에서 명령어로 마크다운 파일 만들기
개요
엔지니어들은 게으름에서 비롯된 이상한 습성을 가진 경우가 있다. 정말 하기 싫은 일이 있으면 엔지니어들은 자신을 대신해 이 일을 해줄 무언가를 만든다. 심지어 이런 것을 만드는 데 걸리는 노력이 원래 하기 싫은 일을 하는 데 드는 노력보다 훨씬 많이 들어도 굳이 이런 짓을 하고는 한다.
한 권으로 읽는 컴퓨터 구조와 프로그래밍 p. 196
그간 고민하고 있던 블로그 플랫폼을 Github Pages
로 옮기게 되었습니다. 그나마 익숙한 Jekyll
을 사용해서 만들었습니다. Jekyll
은 포스트를 날짜-파일제목.md
형식으로 관리하는데요, 저는 이 파일을 만드는 과정이 제법 귀찮게 느껴졌습니다. 요즘 날짜 감각이 없어져서 파일을 생성할 때마다 매번 시간 보는 게 귀찮았거든요. 게다가 저는 _posts
디렉터리에서 연도/월
형식으로 디렉터리를 만들어서 포스트를 관리하려고 했기 때문에 손이 조금 더 갔습니다.
개발자는 귀찮으면? 자동으로 해주는 걸 만들자!
이러한 의식의 흐름으로 Jekyll
포스팅 파일 생성기를 셸 스크립트로 만들었습니다.
그리고 이 글은 셸 스크립트를 만드는 과정을 담았습니다.
만들려는 셸 스크립트의 동작은 이렇습니다.
- 명령어를 실행하는 오늘 날짜를 기준으로
연도/월
디렉터리를 생성합니다. - 인수로 파일 이름을 입력받고,
연도/월/연도-월-일-파일이름.md
파일을 생성합니다. vscode
로 만든 파일을 엽니다.
🗂 연도/월
디렉터리 생성
파일을 먼저 만들어봅시다. 파일은 편한 곳에 만들면 되는데, 나중에 alias
로 등록해서 사용할 거니까 홈 디렉터리가 아니더라도 접근하기 좋은 곳에 만들어줍니다. 저는 홈 디렉터리에 만들었습니다.
$ touch post.sh
파일을 만들었으면 실행 권한을 설정합니다.
$ chmod u+x post.sh
이제 셸 스크립트 파일을 열어서 코드를 작성합니다. 첫 줄은 셸 경로를 적습니다. 일반적으로 다음과 같이 작성합니다.
#!/bin/sh
자, 이제 우리가 만든 셸 스크립트 파일은 파일을 생성하려는 위치가 아니라 홈 디렉터리에 있잖아요? 그래서 파일을 생성할 위치를 찾아야 합니다. 터미널로 본인의 블로그 디렉터리에서 포스트를 관리하는 디렉터리까지 들어갑니다. Jekyll
은 _posts
디렉터리에 포스트를 작성하니까 그곳으로 들어가서 pwd
명령어를 실행합니다.
pwd
명령어는 현재 위치한 곳의 경로를 알려주는 명령어입니다.
$ pwd
/Users/jiwon/Projects/jwonyLee.github.io/_posts
제 블로그 디렉터리 경로는 저렇습니다. 이건 본인의 디렉터리 경로마다 다르니까 참고만 하세요. 아무튼, 이렇게 얻은 경로를 복사해서 셸 스크립트에 변수로 만들어줍니다.
#!/bin/sh
postPath="/Users/jiwon/Projects/jwonyLee.github.io/_posts"
참고로 셸 스크립트에서 =
사이에 띄어쓰기가 있으면 인식을 못 합니다. 예를 들어, postPath = "...."
이렇게 작성하면 제대로 동작하지 않으니 주의해서 작성합니다.
디렉터리를 생성하려면 오늘 날짜가 필요합니다. 년, 월이 따로따로 필요하고, 이후에도 파일을 생성할 때 사용할 예정이기 때문에 일도 포함하여 변수로 만들어 둡니다.
현재 시각을 표시하는 명령어는
date
명령어입니다.
# 오늘 날짜 구하기
currentYear=$(date, '+%Y')
currentMonth=$(date, '+%m')
currentDay=$(date, '+%d')
디렉터리를 만드는 데 필요한 정보는 모두 구했습니다. 이제 디렉터리를 만들어봅시다. 저는 년/월
형태로 포스트를 관리할 것이기 때문에 ../_posts/year/month
형태로 디렉터리를 만들 예정입니다. 년/월
디렉터리가 필요 없으면 이 부분은 건너뛰어도 됩니다.
디렉터리를 만드는 명령어는
mkdir
입니다.
-p
옵션은 인수에 지정한 디렉터리 경로가 존재하지 않으면 그 중간에 있는 디렉터리도 포함해서 새로운 디렉터리를 만듭니다. 예를 들어,2021
디렉터리가 없으면2021
디렉터리를 포함해서2021/08
디렉터리를 만든다는 뜻입니다.
# 오늘 날짜에 맞는 디렉터리 생성
mkdir -p $postPath/$currentYear/$currentMonth
💾 연도/월/연도-월-일-파일이름.md
파일 생성
인수로 파일명과 제목으로 쓸 문자열도 받아봅시다.
명령어 인수는 특수 변수
$1
,$2
,$3
…을 사용합니다.
$ ./post.sh "File Generator"
# 파일명/제목을 인수로 받음
postTitle=$1
인수로 들어온 "File Generator"를 postTitle
변수에 할당합니다. 큰따옴표로 묶지 않으면 띄어쓰기를 했을 때 인수가 띄어쓰기를 기준으로 들어오기 때문에 큰따옴표로 묶어서 인수를 작성합니다.
이렇게 입력받은 postTitle
을 바로 쓸 수 있으면 좋겠지만, 파일명에 띄어쓰기가 들어가는 건 원하지 않기 때문에 필터링해줄 겁니다. 한글, 영어, 숫자를 제외한 특수문자는 거르고 띄어쓰기는 -
로 변환합니다. 여기서는 sed
명령어를 사용했습니다.
sed
명령어에 대한 자세한 내용은sed command in linux
로 검색해보세요.
# 제목을 파일명에 쓸 수 있게 필터링
postTitle=$1
filterPostTitle=$(echo $postTitle | sed 's/[^a-z,A-Z,0-9,가-힣,[:space:]]//g' | tr " " "-")
위에서 구한 오늘 날짜와 filterPostTitle
을 조합해서 파일명을 변수로 만듭니다. 저는 마크다운 파일을 만들 거라서 .md
를 뒤에 붙여줬는데, 원하는 확장자로 변경해서 작성합니다. txt
파일을 만들 거면 .txt
로 바꾸면 됩니다.
# 오늘 날짜 + filterPostTitle로 파일 이름 생성
fileName=$currentYear"-"$currentMonth"-"$currentDay"-"$filterPostTitle".md"
거의 다 왔어요! 파일 내부에 들어갈 내용을 작성합니다. 빈 파일을 만들고 싶다면 이 부분은 생략해도 좋아요. 저는 Jekyll
에서 frontMatter
부분을 작성할 거예요. 추가로 아까 입력받았던 postTitle
을 title에 작성했습니다.
# 파일 상단에 들어갈 내용
frontMatter="---
layout: post
title: $postTitle
subtitle:
categories:
tags: []
publish: false
---"
파일명도 만들었고, 파일에 채울 내용도 만들었으니 파일을 만들어봅시다.
# 파일 생성
newFilePath=$postPath/$currentYear/$currentMonth/$fileName
echo "$frontMatter" > $newFilePath
frontMatter
를 큰따옴표로 묶어준 이유는, 줄 바꿈을 포함해서 작성하고 싶어서입니다. 여기까지 작성하고 셸 스크립트를 실행해보면 원하는 경로에 파일이 생성된 걸 볼 수 있어요!
$ ./post.sh "File Generator"
/Users/jiwon/Projects/jwonyLee.github.io/_posts/2021/08/2021-08-20-File-Generator.md
✍️ 에디터로 파일 열기
파일을 생성한 목적이 글을 쓰기 위해서니 에디터로 파일을 여는 것까지 셸 스크립트에 작성합니다. 저는 vscode
로 글을 쓰기 때문에 vscode
로 열리게 했어요. 원하는 에디터 실행 명령어를 쓰면 됩니다. (예: vi $newFilePath
)
# 에디터로 열기
code $newFilePath
전체 코드
이제 셸 스크립트를 실행하면 디렉터리 생성 + 파일 생성 + 에디터로 열기까지 한 번에! 🥰
⚡️ 명령어 등록
매번 홈 디렉터리에 가서 ./post.sh
을 실행할 수는 없는 모양이잖아요? 현재 위치에 상관없이 실행할 수 있으면 좋겠죠. 셸 스크립트 실행 명령어를 alias
로 지정하면 됩니다.
보통은 ~/.bashrc
에 등록을 하는데요, 저는 zsh
를 쓰고 있어서 ~/.zshrc
에 등록할게요. ~/.zshrc
를 열고 하단으로 내리면 alias
작성 예시가 있어요! 그 아래 줄에 작성합니다. 저는 post
키워드로 실행할 수 있게 해줄 거 에요. 키워드도 원하는 대로 작성하면 되는데, OS 명령어와 겹치는 건 안 좋겠죠?
alias post="~/post.sh"
저장하고 나와서 다음 명령어도 실행합니다.
$ source ~/.zshrc
이제 post.sh
를 일일이 붙일 필요 없이, 아무데서나 post
명령어로 만들었던 셸 스크립트를 실행할 수 있어요!
$ post "File Generator"
💬 마무리
_posts/연도/월/file.md
구조 말고도 원하는 디렉터리 이름을 인수로 받아서 _posts/category/file.md
구조로 만들 수도 있어요. 이건 약간만 응용하면 되니까 따로 첨부하지는 않을게요.
오늘은 Jekyll
블로그에 포스팅할 때마다 매번 마크다운 파일을 생성하는 불편함을 해결하기 위해서 셸 스크립트를 만드는 과정을 작성해봤습니다. 도움이 되셨나요? 도움이 되셨다면 구독과 좋아요가 아니고 리액션 한 번씩만 눌러주세요!
그럼 안녕! 👋
참고 자료
- 리눅스 입문자를 위한 명령어 사전