레이블이 gzip인 게시물을 표시합니다. 모든 게시물 표시
레이블이 gzip인 게시물을 표시합니다. 모든 게시물 표시

httpd content-encoding 헤더 누락 문제

# nginx proxy -> apache httpd 웹서버 구성에서
# apache httpd 2.4 버전업과 brotli(br) 압축을 적용했다.
# 다음과 같이 nginx 에 br 인코딩 헤더로 요청을 준다.
# 참고로 -I 로 헤더만 보는경우 curl 은 HEAD method 로 요청하기 때문에
# 실제 GET 요청에서 응답받는 헤더를 보려면 GET method 로 지정해야 한다.
curl 'http://ysoftman-nginx/test?param=ysoftman'-H 'accept-encoding:br' -I -X GET

# 다음과 같이 content-encoding: br 응답헤더를 볼 수 있다.
HTTP/2 200
date: Thu, 03 Oct 2019 13:13:34 GMT
content-type: text/html; charset=utf-8
vary: Accept-Encoding
content-encoding: br
server: ysoftman-nginx
cache-control: private, no-cache, max-age=0
expires: -1

# gzip 요청도 테스트 해보면
curl 'http://ysoftman-nginx/test?param=ysoftman'-H 'accept-encoding:gzip' -I -X GET

# 다음과 같이 content-encoding: gzip 응답헤더를 볼 수 있다.
HTTP/2 200
date: Thu, 03 Oct 2019 13:09:34 GMT
content-type: text/html; charset=utf-8
vary: Accept-Encoding
content-encoding: gzip
server: ysoftman-nginx
cache-control: private, no-cache, max-age=0
expires: -1

# 문제
# nginx 에서 packetbeat 을 설치해 httpd 의 응답 헤더를 수집해 elasticsearch(es) 보냈다.
# kibana 로 content-encoding 헤더가 br 또는 gzip 을 카운트 하려는데
# http.response.headers.content-encoding 헤더 자체가 없는 로그가 있다.
# "accept-encoding" 요청이 없으면 plain text 로 헤더가 없는게 맞지만
# "accept-encoding: gzip" 요청은 있어야 한다.
# http.response.headers.content-encoding: br 은 잘 남고 있었다.
# 원인
# curl 이나 실제 브라우저에서 테스트 해보면
# content-encoding: br 또는 gzip 응답이 확인된다.
# 하지만 nginx 가 아닌 httpd 로 요청하면
# gzip 요청에 대해선 content-encoding 응답헤더가 없었다.
curl 'http://ysoftman-httpd/test?param=ysoftman'-H 'accept-encoding:gzip' -I -X GET

# gzip 처리를 nginx 가 해줘 nginx 의 packetbeat 은
# httpd 로 부터의 응답에서 "content-encoding: gzip" 찾을 수 없었던 것이다.
# 찾아보니 httpd.conf 에서 응답 필터 처리시
# 다음과 같이 brotli 만 응답 필터링한게 문제였다.
SetOutputFilter BROTLI_COMPRESS

# 해결
# SetOutputFilter 는 주석처리하고
# 다음과 같이 AddOutputFilterByType 로
# deflate(gizp에서 사용하는 무손실 압축 알고리즘), brotli 둘다 사용할 수 있게 했다.
# 먼저 추가한 필터가 우선순위를 가져 br 먼저 설정해야 한다.
AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css text/javascript application/x-javascript application/javascript application/json application/x-font-ttf application/vnd.ms-fontobject image/x-icon

AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/x-javascript application/javascript application/json application/x-font-ttf application/vnd.ms-fontobject image/x-icon

# 그리고 AddOutputFilterByType 사용하려면 filter 모듈을 추가해야 한다.
LoadModule filter_module modules/mod_filter.so

# 이제 httpd 요청시에도 "content-encoding: gzip" 헤더를 받을 수 있고,
# packetbeat 에서도 잘 수집돼 -> es -> kibana 로 content-encoding 값을 구분 할 수 있다.

# 참고
https://httpd.apache.org/docs/current/mod/mod_filter.html#AddOutputFilterByType
https://www.tunetheweb.com/performance/brotli/

mac ls -l @ 확장 속성

# mac(맥)에서 ls -l 로 보면 퍼미션에 @ 가 붙어 있는 파일들을 볼 수 있다.
# 확장속성(extended attribute)을 가진 파일로, 파일시스템에서 파일과 관련된 메타 정보를 명시하고 있다.
# 확장속성의 자세한 내용 https://en.wikipedia.org/wiki/Extended_file_attributes
ls -l
-rw-r--r--@ 1 ysoftman  staff   387 12 20 15:10 iterable.html

# 확장속성이 추가되는 경우
iterm2 -> ls -> .html 파일 cmd+click -> 브라우저로 열였을때

# xattr 로 확장속성 파일의 내용을 확인할 수 있다.
xattr iterable.html
com.apple.lastuseddate#PS
com.apple.metadata:_kMDItemUserTags

# xattr -c 로 파일에서 확상속성을 제거할 수 도 있다.
xattr -c iterable.html

#####

# 맥에서 압축된 파일을 압출 풀때 다음과 같이 경고가 나오고, 추가적인 별도 파일들도 생성된다.
tar zxvf ysoftman.tar.gz
tar: Ignoring unknown extended header keyword 'LIBARCHIVE.xattr.com.apple.LaunchServices.OpenWith'

# 맥에서 확장 속성을 제거한 후 압축 하도록 한다.
# -r : act recursively
# -c : clear
xattr -rc ./ysoftman
tar czf ysoftman.tar.gz ./ysoftman

# 이제 압축 풀면 경고도 없이 압축이 풀린다.
tar zxvf ysoftman.tar.gz

#####

# + 는 ACL permission 속성을 나타낸다.
# xNix 에서 getfacl, setfacl 명령으로 acl 상태 보기 및 설정이 가능하다.

Apache httpd 에서 https http2 brotli 사용하기

# 2019-07-16 최신 버전 기준으로 내용 수정
# HTTP 2 는 기존 HTTP 1.x 의 비효율적인 속도를 개선한 버전으로 Multiplexed Strem, Header Compression 등의 기술이 포함되어 있다.
# 참고
# http://www.bloter.net/archives/210122
# https://icing.github.io/mod_h2/howto.html
# http://httpd.apache.org/docs/trunk/new_features_2_4.html
# http://httpd.apache.org/docs/2.4/programs/configure.html#installationdirectories

# apr 설치
wget http://apache.mirror.cdnetworks.com/apr/apr-1.7.0.tar.gz
tar zxvf apr-1.7.0.tar.gz
cd apr-1.7.0
./configure --prefix=${HOME}/apr
make -j8 && make install

# apr-util 설치
wget http://apache.mirror.cdnetworks.com//apr/apr-util-1.6.1.tar.gz
tar zxvf apr-util-1.6.1.tar.gz
cd apr-util-1.6.1
./configure --prefix=${HOME}/apr-util --with-apr=${HOME}/apr --with-crypto
make -j8 && make install

# openssl 설치
wget https://github.com/openssl/openssl/archive/OpenSSL_1_1_1c.tar.gz
tar zxvf OpenSSL_1_1_1c.tar.gz
cd openssl-OpenSSL_1_1_1c
./config --prefix=${HOME}/openssl -fPIC
make -j8 && make install

# nghttp2 설치
# 아파치 httpd 에서는 mod_http2 모듈을 로딩하여 HTTP 2 처리를 하게 된다.
# 자세한 내용은 https://httpd.apache.org/docs/2.4/mod/mod_http2.html
wget https://github.com/nghttp2/nghttp2/releases/download/v1.39.1/nghttp2-1.39.1.tar.gz
tar zxvf nghttp2-1.39.1.tar.gz
cd nghttp2-1.39.1
./configure --prefix=${HOME}/nghttp2 OPENSSL_CFLAGS="-I${HOME}/openssl/include" OPENSSL_LIBS="-L${HOME}/openssl/lib -lssl -lcrypto"
make -j8 && make install

# brotli 설치
# gzip 보다 향상된 압축방식이다.
# cmake 로 빌드하기 때문에 없으면 설치하자.
sudo yum install cmake
wget https://github.com/google/brotli/archive/v1.0.7.tar.gz
tar zxvf v1.0.7.tar.gz
cd brotli-1.0.7

# 빌드 결과물이 현재 위치에 생성되기 때문에 out 디렉토리를 생성하고 빌드하자.
mkdir -p out
cd out
../configure-cmake --prefix=${HOME}/brotli
make -j8 && make install

# httpd 설치
# 아파치 httpd 2.4.17 (부터 http2 지원) 이후 버전을 설치하자.
wget http://apache.tt.co.kr//httpd/httpd-2.4.39.tar.gz
tar zxvf httpd-2.4.39.tar.gz
cd httpd-2.4.39
./configure \
--prefix=${HOME}/apache-httpd \
--with-apr=${HOME}/apr \
--with-apr-util=${HOME}/apr-util \
--enable-brotli \
--with-brotli=${HOME}/brotli \
--enable-http2 \
--with-nghttp2=${HOME}/nghttp2 \
--enable-ssl \
--with-ssl=${HOME}/openssl \
--with-mpm=prefork \
--enable-mods-shared="unixd authz_core authz_user rewrite authz_host include log_config mime_magic headers unique_id setenvif mime status dir alias"
make -j8 && make install

# 참고
# apr, apr-util 소스를 별도로 빌드하지 않고
# httpd/srclib/apr, httpd/srclib/apr-util 이름으로 압축을 해제하면
# --with-apr --with-apr-util 옵션을 사용하지 않고 httpd 빌드할 수 있다.
# libapreq 설치
wget http://mirror.apache-kr.org//httpd/libapreq/libapreq2-2.13.tar.gz
tar zxvf libapreq2-2.13.tar.gz
cd libapreq2-2.13
./configure --with-apache2-apxs=${HOME}/apache-httpd/bin/apxs

# ${HOME}/apache-httpd/modules/mod_apreq2.so 로 설치된다.
make -j8 && make install

# http2 를 사용할 수 있도록 설정파일에 다음을 추가한다.
sudo vi conf/httpd.config
LoadModule http2_module modules/mod_http2.so
<IfModule http2_module>
LogLevel http2:info
</IfModule>

# h2 -> TLS(SSL) https 로 요청되는 경우
# h2c -> http 로 요청되는 경우
Protocols h2 h2c http/1.1

# 아파치 httpd 시작시 nghttpd 라이브러리를 참조할 수 있도록 환경변수 스크립트 수정
# 기존 경로에 openssl 과 nghttp2 를 추가해 준다.
vi ${HOME}/apache-httpd/bin/envvars
LD_LIBRARY_PATH="${HOME}/apache-httpd/lib:${HOME}/openssl/lib:${HOME}/nghttp2/lib:$LD_LIBRARY_PATH"
export LD_LIBRARY_PATH

# brotli 설정 추가
sudo vi conf/httpd.config
LoadModule brotli_module modules/mod_brotli.so
SetOutputFilter BROTLI_COMPRESS

# 아파치 httpd 시작~
sudo ${HOME}/apache-httpd/bin/apachectl -k start

# gzip brotli 압축 사용시 사이즈 보기
curl -H "Accept-Encoding: gzip" -o out.gz https://ysoftman.com/test
curl -H "Accept-Encoding: br" -o out.br https://ysoftman.com/test

# gzip 압축해제
gzip -d -k out.gz

# brotli 압축해제
# brew install brotli 설치
# https://github.com/google/brotli/blob/master/c/tools/brotli.md

vim command

[vim 설치]
# vim 은 vi 를 향상시킨 버전으로 GUI 용인 gVim 도 있다.
# 윈도우 또는 소스설치는 vim 사이트에서 다운로드
http://www.vim.org/
# 레드햇 계열 리눅스
sudo yum install vim
# 데미안 계열 리눅스
sudo apt-get install vim

[용어]
normal 모드 : 기본 모드로 명령을 실행할 수 있는 상태로, 다른 모드로 전환하기 전의 상태
insert 모드 : i, a 등으로 수정(쓰기)작업을 할 수 있는 상태 
visual 모드 : v 로 특정 블럭을 지정(선택)할 수 있는 상태
register : yank(copy역할)등으로 저장된 메모리 공간(클립보드 역할)
buffer : 파일을 읽어 놓은 메모리 공간, 버퍼 수정 저장해야 파일로 쓰게 된다.
window : 버퍼 내용이 표시되는 화면
tab : 여러 windows 들의 모음

[.vimrc 설정 예시]
" vimrc 에서 주석은 " 를 사용한다.
" ysoftman .vimrc 설정
syntax on
color elflord
set number
set hlsearch
set incsearch
set backspace=indent,eol,start
set enc=utf-8
set fencs=utf-8,cp949
set tabstop=4
set autoindent
" gvim 의 경우 source $VIMRUNTIME/vimrc_example.vim 에서 텍스트 파일을 열때 textwidth=78 로 설정하고 있는데 이를 수정함
autocmd FileType text setlocal textwidth=0 tabstop=4 shiftwidth=4
if has("gui_running")
 set guifont=나눔고딕코딩:h10 " 폰트 설정
 au GUIEnter * winsize 100 50 " 시작시 윈도크 크기 설정
endif

[vim 명령어]
esc (ctrl+c 명령 취소)
syntax on (신택스 기능 활성화)
color elflord 또는 colorscheme elflord (컬러설정, syntax 활성화되어야 함)
highlight Normal ctermbg=none (하이라이트로 normal 그룹에 color terminal background 색은 무시, 컬러스킴의 black 아닌 none 값으로 검은색 배경이 된다.)
highlight ColorColumn ctermbg=brown (colorcolumn 색변경, 컬러스킴 설정 후 에 명시해야 적용된다.)
ctrl+w n (새창 만들기, :new)
ctrl+w s (현재파일을 수평창으로 나눔, :sp)
ctrl+w v (현재파일을 수직창으로 나눔, :vs)
ctrl+w = (창들을 균등하게 분할)
ctrl+w w 또는 방향키 또는 h,j,k,l 방향키 (창들간에 이동)
ctrl+w H (현재 창을 왼쪽으로 이동)
ctrl+w L (현재 창을 오른쪽으로 이동)
ctrl+w J (현재 창을 아래쪽으로 이동)
ctrl+w K (현재 창을 위쪽으로 이동)
20ctrl+w _ (창 높이를 20라인 크기로 조정, :resize 20) 
100ctrl+w | (창 폭을 100컬럼 크기로 조정, :vertical resize 100)
ctrl+f (page down)
ctrl+b (page up)
ctrl+d (반페이지 down)
ctrl+u (반페이지 up)
ctrl+v (visual block mode, 세로로 블럭 지정 가능)
insert 모드에서 ctrl+v숫자 (터미널로 입력되는 특수키 문자 파악, 예를 들어 숫자에 027입력하면 ^[ --> ESC 키로 ^와[ 를 조합된게 아님, 065는 A로 표시된다)
ctrl+z (vim 중지하고 백그라운드로 전환해 쉘이 보임, fg 로 vim으로 다시실행, :sh 와 exit 도 같은 기능)
h (커서 왼쪽 이동)
l (커서 오른쪽 이동)
j (커서 아래쪽 이동)
k (커서 위쪽쪽 이동)
2h (커서 왼쪽 2칸 이동)
2l (커서 오른쪽 2칸 이동)
2j (커서 아래쪽 2줄 이동)
2k (커서 위쪽쪽 2줄 이동)
10G (10 라인으로 이동)
10+ (현재 라인에서 10 라인 아래로 이동)
10- (현재 라인에서 10 라인 이전으로 이동)
H (현재 화면에서 첫 라인으로 이동)
M (현재 화면에서 중간 라인으로 이동)
L (현재 화면에서 마지막 라인으로 이동)
~ (현재 커서 대문자 -> 소문자, 소문자 -> 대문자 변환)
J 또는 블럭 선택 후 :join (현재 라인의 맨끝에서 라인 2개를 1개로 합친다. 합쳐진 라인의 indent 는 삭제되고 공백이 추간된다. 블럭으로 멀티 라인을 선택해서 합칠 수도 있다.)
u (최근 편집명령 하나 취소)
u (visual 모드, 선택한 블럭 소문자로 변환)
U (visual 모드, 선택한 블럭 대문자로 변환)
r (현재 커서 글자 하나 수정)
R (Replace mode, 모든 문자위에 덮어 쓰기 할 수 있는 상태가 된다.)
I (insert 모드, 현재줄 맨 앞에 추가)
A (insert 모드, 현재줄 맨 끝에 추가)
i (insert 모드, 커서 앞에 추가)
a (insert 모드, 커서 뒤에 추가)
v (visual 모드, 블럭 문자 단위 지정, :로 명령모드에서 :'<,'> 로 자동 입력)
V (visual 모드, 블럭 라인 단위 지정, :로 명령모드에서 :'<,'> 로 자동 입력)
y (visual 모드에서 지정한 블럭 register 로 복사)
yy (커서가 있는 라인을 복사)
yb (커서부터 단어의 앞까지 복사)
yw (커서부터 단어의 뒤까지 복사)
p (커서 뒤에 1번 붙여넣기, np 하면 n번 반복)
P (커서 앞에 1번 붙여넣기, nP 하면 n번 반복)
n| (현재라인에서 n컬럼으로 이동)
f문자 (현재라인에서 오른쪽방향으로 문자가 있는곳으로 이동)
F문자 (현재라인에서 왼쪽방향으로 문자가 있는곳으로 이동)
t문자 (현재라인에서 오른쪽방향으로 문자가 있는곳 한칸 전으로 이동)
T문자 (현재라인에서 왼쪽방향으로 문자가 있는곳 한칸 전으로 이동)
; (f,F,t,T문자 이동 반복)
n% (파일의 n%퍼센트 라인으로 이동)
x (한글자 삭제)
ggdG (전체 삭제, 파일 처음 위치로 가서 파일 끝까지 삭제)
횟수dw (횟수만큼 dw 수행)
횟수dd (횟수만큼 dd 수행)
dw (커서가 있는 단어 삭제)
dd (커서가 있는 라인 삭제)
d^ (커서 부터 라인 시작까지 삭제)
d$ 또는 D (커서 부터 라인 끝까지 삭제)
diw (delete inner word, 현재 커서가 있는 단어 하나 삭제, 커서가 공백 위라면 공백만 삭제)
daw (delete a word, 현재 커서가 있는 단어 하나 삭제)
dis (delete inner sentence, 현재 커서가 있는 문장(. ! ? 공백 탭등으로 구분) 삭제, 커서가 문장 사이에 공백 위라면 공백만 삭제)
das (delete a sentence, 현재 커서가 있는 문장((. ! ? 공백 탭등으로 구분) 삭제)
dt문자 (현재 커서에서 문자 전 까지 삭제)
df문자 (현재 커서에서 문자 까지 삭제)
d/스트링 (현재 커서에서 스트링이 있는 곳까지 삭제)
cb (현재 커서 이전부터 단어 시작까지 삭제(register 에 저장)하고 insert 시작)
cw 또는 ce (현재 커서부터 단어까지 삭제(register 에 저장)하고 insert 시작)
cc 또는 S (현재 라인 삭제(register 에 저장함)하고 insert 시작)
ciw (현재 커서가 있는 단어 하나 삭제(공백 미포함, 커서가 공백 위라면 공백만 삭제) 후 insert 모드)
caw (현재 커서가 있는 단어 하나 삭제(공백 포함) 후 insert 모드)
ci( 또는 ci) (현재 커서에서 가장 가까운 () 내용 삭제 후 insert 모드)
ca( 또는 ca) (현재 커서에서 가장 가까운 ()과 () 내용 삭제 후 insert 모드)
ci{ 또는 ci} (현재 커서에서 가장 가까운 {} 내용 삭제 후 insert 모드)
ca{ 또는 ca} (현재 커서에서 가장 가까운 {}과 {} 내용 삭제 후 insert 모드)
s (현재 문자 삭제(register 에 저장함)하고 insert 시작)
. (마지막 명령 반복 수행)
qa (a 이름의 매크로 기록 시작)
q (매크로 기록 종료)
@a (a 매크로 실행)
@@ (이전 실행한 매크로 실행)
10@a (a 매크로 10번 실행)
$ (현재 라인의 끝으로 이동)
0 (현재 라인의 시작으로 이동)
^ 또는 _ (현재 라인의 공백아닌 첫문자로 이동)
+ 또는 ctrl+m (다음 라인의 공백아닌 첫문자로 이동)
- (이전 라인의 공백아닌 첫문자로 이동)
w (다음 단어의 첫문자로 커서이동)
W (공백으로 구분되는 다음 단어의 첫문자로 커서이동)
e (다음 단어의 마지막 문자로 커서이동)
E (공백으로 구분되는 다음 단어의 마지막 문자로 커서이동)
b (한단어 뒤로 단어의 첫문자로 커서 이동)
B (공백으로 구분되는 한단어 뒤로 단어의 첫문자로 커서이동)
t문자 (현재 라인에서 오른쪽 방향으로 문자 위치 바로전으로 커서 이동)
f문자 (현재 라인에서 오른쪽 방향으로 문자 위치로 커서이동)
T문자 (현재 라인에서 왼쪽 방향으로 문자 위치 바로전으로 커서 이동)
F문자 (현재 라인에서 왼쪽 방향으로 문자 위치로 커서이동)
V(비주얼모드로 블럭선택후) > (sw 크기 만큼 오른쪽으로 이동, indent)
V(비주얼모드로 블럭선택후) < (sw 크기 만큼 왼쪽으로 이동)
>> (sw 크기 만큼 오른쪽으로 이동, indent)
<< (sw 크기 만큼 왼쪽으로 이동)
{ (이전 문단으로 이동)
} (다음 문단으로 이동)
[[ (이전 섹션으로 이동)
]] (다음 섹션으로 이동)
% (현재 커컷상의 ([{}]) 에 짝이 되는 곳으로 이동)
# (현재 커서상의 워드 문자열 찾고 이전으로 이동)
* (현재 커서상의 워드 문자열 찾고 다음으로 이동)
/string (문자열 앞으로 찾기, n 으로 다음찾기)
/\cstring 또는 /string\c (\c로 주면 대소문자 구분없이 찾기)
/\Cstring 또는 /string\C (\C로 주면 대소문자 구분해서 찾기)
/대상1\|대상2\|대상3  (\| 구분으로 여러개 한번에 찾기)
?string (문자열 뒤로 찾기, n 으로 이전찾기)
n (찾은 문자열들 중에서 다음으로 이동)
N (찾은 문장열들 중에서 이전으로 이동)
gf (명시된 파일로 바로가기(열기))
gd (현재 단어(변수) 현재 파일내에서 정의 위치로 가기)
gD (현재 단어(변수) 현재 함수내에서 정의 위치로 가기)
gt (다음 탭으로 이동 :tabn)
gT (이전 탭으로 이동 :tabp)
m{a-z} (ma 하면 a이름으로 마크, 현재 버퍼내에서만 마크됨, 다른 파일에선 마크로 이동 못함)
m{A-Z0-9} (mA 하면 A이름으로 마크, 파일까지 마크됨, 다른 파일에서도 마크로 이동 가능)
'마크이름 (마크 위치의 라인 첫위치로 이동)
`마크이름 (마크 정확한 위치로 이동)
ctrl+6 (이전 파일 열기)
ctrl+o (이전 위치로 점프)
ctrl+i (앞 위치로 점프)
v zf (블럭 선택 후 블럭 폴딩/닫기)
zo (폴딩된 라인에서 폴딩 열기)
zd (폴딩 삭제)
zk (이전 폴딩으로 이동)
zj (다음 폴딩으로 이동)
zM (모든 폴딩 닫기) 
zR (모든 폴딩 열기) 
= (프로그램 소스코드에서 v 로 영역을 선택하고 = 누르면 선택된 영역들의 줄들이 알맞게 들여쓰기됨)
== (현재 라인 들여쓰기)
gg=G (파일 처음부터 끝까지 알맞게 들여쓰기됨)
=% (프로그램 소스코드에서 시작블럭{ 이나 끝블럭} 에서 =% 누르면 블럭내의 줄들이 알맞게 들여쓰기됨)
K (현재 커서에 대한 대문자 메뉴얼 페이지 보기)
ctrl+r (최근 취소된 편집명령 복구)
ctrl+g (현재 파일이름과 라인수 보기)
ctrl+n (자동완성 리스트에서 다음 항목)
ctrl+p (자동완성 리스트에서 이전 항목, 프로그래밍시 함수,변수에서 ctrl+p 하면 자동완성, 예를 들어 int YoonByoungHon = 0; 후 다음 줄에서 Yo부분에서 ctrl+p 하면 YoonByoungHoon 이 바로 입력되거나 Yo 로 시작하는 리스트중에서 선택가능)
"레스트터이름명y (레지스터에 내용 복사)
"레스트터이름명p (레지스터의 내용 붙여넣기)
"+y (+는 CLIPBOARD, vim -> CLIPBOARD 으로 복사)
"+p (+는 CLIPBOARD, CLIPBOARD -> vim 으로 붙여 넣기)
:reg (레지스터 내용 보기, type -> c:characterwise, l:linewise, b:blockwise-visual)
:help 또는 :h (도움말 보기)
:help i (i 도움말보기)
:help :e (:e 도움말보기)
:help ctrl-r (ctr+r 도움말보기)
:messages (vim 이 출력하는 메시지 보기)
:stop 또는 :suspend (suspend vim 로 ctrl+z 와 같다.)
:color 또는 colo 또는 colorschem (현재 설정된 컬러 스킵 보기, 공백 후 tab, shift-tab 을 누르면 사용 가능한 컬러 스킴이름이 표시된다.)
:intro (인트로 화면 보기)
:print (현재 커서 위치의 라인 내용 출력)
:language 또는 lang (현재 언어 설정 보기)
:!외부명령 (외부명령실행, 예를 들어 !ls -ahl 하면 는 ls -ahl 실행)
:f (현재 파일이름과 라인 수 보기)
:n (n라인으로 이동)
:% (%는 현재파일을 의미한다. 파일 전체 범위 지정, :1,$ 와 같다.)
:0 또는 gg (파일의 첫번째 행으로 이동)
:$ 또는 G (파일의 마지막 행으로 이동)
:e filename (파일 새로 열기(버퍼), :e filename 입력시 ctrl+d 하면 현재 위치의 파일 리스트 표시)
:e ++enc=cp949 (cp949 인코딩으로 다시 열기, 참고로 .vimrc 에서 set fencs=utf-8,cp949 하면 알맞은 인코딩을 파일을 연다)
:e! (파일 다시 읽기)
:noau e filename.gz 또는 vi -c "noau e filename.gz" (gzip 파일 압축해서해서 열지 않기, vim 은 기본적으로 gzip 파일은 압축해서 연다.)
:bp 또는 bprevious (이전 버퍼로 이동, 버퍼는 메모리에 올라가 있는 파일로 vim a.txt b.txt 했을때 2개의 텍스트 버퍼가 생성된다. 화면 위에 버퍼 내용들이 표시된다.)
:echo 표현 (뒤 오는 표현 내용 출력)
:echo winnr() (현재 창 번호 출력)
:echo winnr('$') (마지막 현재 창 번호 = 창 개수 출력)
:echo bufnr() (현재 버퍼 번호 출력)
:echo bufnr('$') (마지막 버퍼 번호 출력)
:bn 또는 :bnext (다음 버퍼로 이동)
:bd 또는 :bdel (현재 버퍼 삭제/닫기)
:buffers 또는 :ls 또는 :files (버퍼 리스트 보기)
:%bwipeout 또는 :%bw (모든 버퍼 삭제/닫기)
:tabs (탭 리스트 정보)
:tabe 또는 :tabnew (새탭열기) 또는 :tabe 파일명
:tabc 또는 :tabclose (현재 탭닫기, tabc! 저장하지 않고 닫기)
:tabo (모든 탭 닫기, tabo! 저장하지 않고 닫기)
:tabp 또는 :tabprevious 또는 gT (이전 탭으로 이동, vim -p a.txt b.txt 했을때 2개의 탭으로 열린다.)
:tabn 또는 :tabnext 또는 gt (다음 탭으로 이동, tabn3 3번 탭으로 이동)
:marks (마크 리스트)
:delmarks 마크이름 (:delmarks a b 하면 a와 b 마크 지우기, :delmarks \" 하면 " 마크 지우기, delmarks 0-9 a-z A-Z 숫자,영문자 마크 모두 삭제, ' 이름의 마크는 바로 이전 위치에 대한 마크로 삭제할 수 없다.)
:new (새창 만들기)
:sp (수평으로 창을 나누기)
:vs (수직으로 창을 나누기)
:sp 파일명 (수평으로 창을 나누고 파일 열기)
:vs 파일명 (수직으로 창을 나누고 파일을 열기)
:Explore (현재 파일 탐색 표시, 탐색창에서 o 는 파일 열기, p 는 파일 프리뷰)
:Sexplore (수평으로 창을 나누고 탐색 표시)
:Vexplore (수직으로 창을 나누고 탐색 표시)
:ju 또는 :jumps (점프 리스트 표시, 점프는 ctrl+o(이전위치), ctrl+i(앞위치))
:clearjumps (현재 윈도우 점프 리스트 지우기)
:sh (잠시 쉘로 나가기, 쉘에서 exit 하면 vi로 복귀)
:copen (quickfix list 창 열기)
:ccl 또는 :cclose (quickfix list 창 닫기)
:cw 또는 :cwindow (에러 있으면 quickfix list 창 열기)
:cl 또는 :clist (quickfix list 보기)
:cn (quickfix list 중 다음 항목)
:cp (quickfix list 중 이전 항목)
:cfirst (quickfix list 중 첫번째 항목)
:clast (quickfix list 중 마지막 항목)
:cfdo 명령 (quickfix list 항목별 명령 실행)
:lopen (location list 창 열기)
:lcl 또는 :lclose (location list 창 닫기)
:lnext (location list 중 다음 항목)
:lprev (location list 중 이전 항목)
:lfirst (location list 중 첫번째 항목)
:llast (location list 중 마지막 항목)
:retab (set expandtab 으로 탭입력이 스페이스로 변경되는 상태에서, 모든 tab 을 space 로 변경)
:retab! (set noexpandtab 으로 탭입력이 스페이스로 변경되지 않는 상태에서, 모든 space 를 tab 으로 변경)
:set all (모든 설정 보기)
:set 설정명 (설정 값 보기)
:set enc=utf-8 (인코딩 utf-8 로 사용)
:set visualbell t_vb= (beep 대신 t_vb 로 설정된 문자로 표시하는데 설정 문자가 없어 visual bell 도 사용하지 않게 된다.)
:set hidden (버퍼 숨김 활성화, 버퍼를 수정 후 파일로 저장하지 않아도 다른 버퍼로 이동 :bn 할 수 있다. 숨김이 비활성화되어 있으면, 버퍼를 수정 후 저장해야 다른 버퍼로 이동 할 수 있다.)
:set autoread (파일 자동 refresh)
:set updatetime=1000 "화면 갱신 주기(default: 4000ms), 커서 사용중일때는 갱신 않함
:set laststatus=2 (상태바 활성 0:비활성 1:윈도우가2개이상일때(디폴트) 2:항상)
:set showtabline=2 (탭바 활성 0:비활성 1:탭이2개이상일때(디폴트) 2:항상) 
:set mouse=a (gui 환경에서 마우스 사용 가능, 기본 mouse="")
:set number 또는 :set nu (라인 번호 표시, 끝에 !붙이면 토글)
:set nonumber 또는 :set nonu (라인 번호 표시 안하기)
:set relativenumber 또는 :set rnu (라인 번호 표시, 끝에 !붙이면 토글)
:set incsearch 또는 :set is (키 입력 마다 찾기 결과 표시)
:set noincsearch 또는 :set nois (키 입력 후 엔터시에만 찾기 결과 표시)
:set hlsearch (검색결과 하이라이트)
:nohl (하이라이트 제거)
:highlight (하이라이트 색설정 상태)
:set showcmd (명령모드에서 명령 표시, 비주얼 모드에서 선택크기 표시)
:set cursorline 또는 :set cul (현재 커서 라인 하이라이팅 활성화)
:set nocursorline 또는 :set nocul (현재 커서 라인 하이라이팅 비활성화)
:set cursorcolumn 또는 :set cuc (현재 커서 컬럼 하이라이팅 활성화)
:set nocursorcolumn 또는 :set nocuc (현재 커서 컬럼 하이라이팅 비활성화)
:set colorcolumn=100 (컬럼 가이드 라인 컬러로 보이기)
:set syntax=sh (파일 타입을 .sh 로 설정)
:set autoindent (자동들여 쓰기 활성화)
:set noautoindent (자동들여 쓰기 비활성화)
:set cindent (C 프로그래밍용 들여쓰기 활성화)
:set nocindent (C 프로그래밍용 들여쓰기 비활성화)
:set wrap (자동 줄 바꿈)
:set nowrap (자동 줄 바꿈 안하기)
:set textwidth=n (n만큼 텍스길이기 넘으면 다음줄로 이동, 0이면 다음줄 이동 제한 없음)
:set ignorecase 또는 :set ic (찾기시 대소문자 무시)
:set noignorecase 또는 :set noic (찾기시 대소문자 구분)
:set lines (라인 크기 설정보기)
:set lines=80 (라인 80 로 설정)
:set list (탭,스페이스,엔터 등의 기호 표시)
:set listchars=tab:→\ ,space:·,trail:·,precedes:«,extends:»,eol:↵ (탭,공백,라인끝공백,접기,펼치기,엔터 문자 설정)
:set nolist (탭,스페이스,엔터 등의 기호 표시 안하기)
:set ts=n 또는 :set tabstop=n (탭크기를 n으로 설정)
:set sw=n 또는 :set shiftwidth=n (들여쓰기 >>, 내여쓰기 <<, 될때 또는 엔터등으로 자동 들여쓰기 될때 이동 크기)
:set et 또는 :set expandtab (탭키 입력시 탭 대신 tabstop=n 만큼의 스페이스 사용)
:set noet 또는 :set noexpandtab (et 비활성화, 탭키 입력시 탭 사용)
:set esckeys (insert 모드에서 방향키 제대로 작동시키기)
:set backspace=indent,eol,start (insert 모드에서 백스페이스 제대로 작동시키기)
:set paste (붙여넣기모드,텍스트를 복사 후 vim 에 붙여넣기하면 autoindent, textwidth 등의 값이 설정 되어 있는 경우 계단처럼 들여쓰기 되는 현상이 발생한다. set paste 를 수행하면 autoindent, textwidth 등의 값을 리셋하거나 비활성하여 있는 그대로 붙여넣을 수 있다.)
:set shellcmdflag=-ic (vim 에서는 .bashrc 를 로딩하지 않아 :!alias명령을 실행 할 수 없는데 shell 에 -i (inertactive 모드로 .bashrc 을 로딩하는 새로운 쉘 생성) -c (뒤에 오는 스트링을 명령으로 처리한다.) 옵션을 주어 alias 명령도 실행하도록 한다.)
:set tm=1000 또는 :set timeoutlen=1000 (맵핑키 입력 완료까지의 대기시간ms, 기본 1000, ttm<0 이면 키코드(<esc><up><enter>등)도 tm 값으로 대기한다.)
:set ttm=50 또는 :set ttimeoutlen=50 (ttm>=0 일때 키코드의 입력 후 대기시간ms, 기본:-1)
:let (변수 설정 모두 보기)
:let 변수명 또는 :echo 변수명 (변수 값 보기)
:let 변수명=값 (내부 변수 설정, g:변수명 전역변수, b:변수명 버퍼변수)
:let mapleader = "," (leader 키 , 로 설정, 디폴트는 \ => "\\" 로 설정)
:verbose set (설정된 모든 옵션 보기)
:verbose set 옵션이름 (옵션에 대한 상태 보기, tabstop 옵션 상태 보기 예) :verbose set tabstop)
:10, 100 d (10~100번재 행 삭제)
:w (저장)
:w 파일명 (파일명으로 저장)
:w! (강제로 저장)
:q! (저장하지 않고 종료)
:qall! (저장하지 않고 모든 열려있는 창 종료)
:wq (저장하고 종료)
:wa (변경파일 모두 저장)
:xa (변경파일 모두 저장 후 종료)
:%!xxd (%파일전체, !외부명령, xxd 명령 실행, hex 모드) 또는 :%!hexdump -C (hexdump 명령 실행, -C(canonical hex+ASCII) hex 모드)
:%!xxd -r (xxd 명령 실행, hex 모드 해제)
:g/문자/d (파일 전체에서 문자가 포함된 라인들 모두 삭제)
:g/문자/m 0 (파일 전체에서 문자가 포함된 라인들 모두 0번째 아래로 이동)
:g/문자/m -2 (파일 전체에서 문자가 포함된 라인들 한줄 위로 이동)
:g/문자/m +1 (파일 전체에서 문자가 포함된 라인들 한줄 아래로 이동)
:%s/문자//gn (파일전체에서 문자 개수 파악)
:s/문자1/문자2/ (현재라인에서 문자1을 문자2로 바꾼다.)
:s#문자2#문자2# (구분자를 # 로 사용할 수도 있다.)
:s/문자1/문자2/i (대소문자 무시한 문자1을 문자2로 바꾼다.) 
:%s/문자1/문자2/gc (파일전체범위(%), g 옵션이 없으면 각 라인에서 첫번째로 매칭된는것 하나만 변경된다. c를 붙이면 바꿀때 물어본다.)
:%s/\//문자2/ (/ 자체를 문자2로 변경하기)
:%s#/#문자2# (/ 자체를 문자2로 변경하기)
:%s/\n/\r\r/ 또는 :%s/\n/ctrl+v 후 엔터입력/ (2줄씩 줄바꿈, 줄바꿈 문자변경시 검색부분은 \n 변경부분 \r 를 사용해야 한다.)
:라인번호1,라인번호2s/문자1/문자2/ (라인번1~2 사이에서 문자1 문자2로 바꾼다.)
:'<,'>s/.\{2}$// (블록지정 후 :s/.\{2}$//) (블럭지정된 영역의 마직막 2글자 삭제)
:map 매핑키 매핑내용 (Normal, Visual, Seclt 모드에서 동작하는 키 매핑, 재귀적 매핑, map a b 과 map b c 로 하면 a -> c 로 매핑될 수 있다. map, noremap 은 Normal, Visual, Select, Operator-pending 모드에서 키 매핑을 사용할 수 있다. :h map-table 참고)
:noremap 매핑키 매핑내용 (Normal, Visual, Select 모드에서 동작하는 키 매핑, 비재귀적 매핑)
:nmap 매핑키 매핑내용 (Normal 모드에서만 동작하는 키 매핑)
:nnoremap 매핑키 매핑내용 (Normal 모드에서만 동작하는 키 매핑, 비재귀)
:vmap 매핑키 매핑내용 (Visual, Select 모드에서만 동작하는 키 매핑)
:vnoremap 매핑키 매핑내용 (Visual, Select 모드에서만 동작하는 키 매핑, 비재귀)
:imap 매핑키 매핑내용 (Insert 모드에서만 동작하는 키 매핑)
:inoremap 매핑키 매핑내용 (Insert 모드에서만 동작하는 키 매핑, 비재귀)
:cnoreabbrev 매핑키 매핑내용 (Command 모드에서 축약어 매핑, 비재귀)
:function 설정된 함수리스트 보기
:scriptnames 설치된 플러그인 리스트 보기
:so ~/.vimrc 또는 :source ~/.vimrc (수정된 vimrc 설정 반영)

[mac option(alt,meta) 키 동작 안되는 문제 해결하기]
mac 에선 기본적으로 option 키가 조합되면 특정 문자로 취급된다.
option+a == å
option+d == ∂
option+p == π
사실 option 는 alt 와 다르고, 각 터미널에 따른 설정이 필요하다.
iterm --> option 키 normal --> esc+
kitty --> macos_option_as_alt no
alacritty
--> alt_send_esc: true 는0.12.0 에서 디폴트로 설정에서 제거됨
--> windows > option_as_alt: Both 로 설정함
:h key-notation 참고

[remove trailing whitespace, 라인끝 공백 제거]
% 파일전체범위, s 바꾸기, \s\+ 공백1개이상, $ 끝에서, // 빈값으로, e 에러 메시지 표시하지 않기
:%s/\s\+$//e

[블럭내 변경]
1. visual 모드에서 v 로 블럭 지정
2. :입력(자동으로 :'<,'> 로 변경)s/대상문자/변경될문자/g

[블럭내 정렬]
1. visual 모드에서 v 로 블럭 지정
2. :입력(자동으로 :'<,'> 로 변경)sort

[멀티라인 수정]
1. 라인 처음으로 커서를 위치 시키고 블록 모드로 변경 ctrl+v
2. 커서로 아래(또는 j)로 멀티 라인 선택
3. 블럭 첫음에 추가시: I(shift+i)로 첫번째 라인 처음에 문자 insert
또는
블럭 수정(삭제하고 입력모드)시: c 로 수정
또는
블럭 끝에 추가시: $로 모든 라인의 끝까지 선택 후 A(shift+a)로 문자 append
4. esc 하면 선택한 전체 라인 반영
참고로 c로 수정하는것 외 insert/append 시 삭제만 하면 멀티 라인으로 반영되지 않는다.

[멀티 커서(선택)로 리팩토리링(변경)하기]
1. v로 검색할 부분 지정 후 ctrl+n 로 선택하고 다음 찾기 (ctrl+x는 스킵, ctrl+p는 현재 선택해제 후 이전 선택으로 이동)
2. I 로 insert 모드 시작 또는 c 로 삭제 후 insert 모드 시작
3. 수정 후 esc 로 종료

[블럭단위 찾기]
1. v 로 블록지정
2. y (yank 로 디폴트 레지스터에 저장)
3. / 찾기모드 변경
4. ctrl+r, " (디폴트 레지스터의 내용 붙여넣기)

[파일들에서 찾아 변경하기]
1. :Rg ysoftman-apple
2. ysoftman-apple 포함된파일들이 보이고, tab또는ctrl+i 으로 선택/해제(alt+a전체선택, alt+d전체해제)후 엔터치면 quickfix 창이 생기고 선택한 목록들이 보인다.
3. quickfix 내 항목들에 대해 변경 명령을 수행, update 변경된 버퍼 저장
cfdo %s/ysoftman-apple/ysoftman-lemon/gc | update