koodev

'bash'에 해당되는 글 2건

  1. Bash에서 문자열 검색 조건식 만들기
  2. Truncate PWD in prompt (MacOS)

Bash에서 문자열 검색 조건식 만들기

Programming

이전에 다른곳에 썼던 내용을 이 블로그에 기록함.

안드로이드 빌드 스크립트를 만들다가 PATH 변수에 특정 문자열이 없을 경우 이를 추가해주는 기능이 필요했다. 관련 내용을 구글링해보니 대부분 문자열 치환에 대해서만 다루고 있었는데, stackoverflow 에서 마침내 원하는 답을 찾을 수 있었다.

http://stackoverflow.com/questions/229551/string-contains-in-bash

string = 'My long string';
if [[$string == *"My long"*]]
then
    echo "It's there!";
fi

이런식으로 대괄호 두개와([[, ]]) 와일드카드 캐릭터(*)를 써서 패턴 검사가 가능하다. 부정 연산자를 넣기 위해 좀 삽질을 했는데, 아래와 같이 ==을 !=으로 바꾸어주면 된다.

JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
if [[$PATH != *"$JAVA_HOME"*]]; then
    export PATH=$PATH:$JAVA_HOME/bin
fi

'Programming' 카테고리의 다른 글

ARM A64 명령어셋 ZIP1, ZIP2  (0) 2019.03.11
ARM A64 명령어세트 기본적인 내용 정리  (0) 2019.03.11
Truncate PWD in prompt (MacOS)  (0) 2018.04.29
Regular expression in sed  (0) 2018.04.25
How to terminate a background process  (0) 2018.04.24

Truncate PWD in prompt (MacOS)

Programming

쉘 프롬프트에 현재 디렉토리 위치를 넣을 경우, 디렉토리 깊이가 깊어질수록 터미널이 지저분해지게 된다. Ubuntu 등의 배포판에서는 PROMPT_DIRTRIM 변수에 숫자를 지정해주면 그 숫자만큼만 프롬프트상에 표시되는 현재 디렉토리 경로를 줄여준다. 그렇지만 MacOS 기본 Bash 쉘(3.2.57)에는 PROMPT_DIRTRIM 이 구현되어 있지 않다. Bash 자체 버전을 올려도 되지만, 순정 상태를 건드리고 싶지는 않다(...). 그런데 손으로 구현하는 방법이 있어 정리해둔다.

참고: https://stackoverflow.com/questions/26554713/how-to-truncate-working-directory-in-prompt-to-show-first-and-last-folder

PS1='$(pwd | sed -E -e "s|^$HOME|~|" -e '\''s|^([^/]*/[^/]*/).*(/[^/]*)|\1..\2|'\'') \$ '

위 스택오버플로 페이지의 솔루션은 좋긴 하지만 처음 두 개 디렉토리 .. 마지막 하나의 디렉토리 로 구성된다. 이것을 조금 바꾸어 처음 1개의 디렉토리 .. 마지막 두개의 디렉토리 으로 만들고 싶다. 아무래도 뒤에 있는 경로가 좀 더 중요하니까. 따라서 스택오버플로 솔루션에서 순서를 바꾸어야 한다.

    PROMPT_PRE='\[\033[38;5;11m\]\u\[\033[38;5;15m\]@\h:\[\033[38;5;6m\]'
    PROMPT_POST='\[\033[38;5;15m\] '
    PWDTRIM1='$(pwd | sed -E -e "s|^$HOME|~|" -e '\''s|^([^/]*/[^/]*/).*(/[^/]*)|\1..\2|'\'')'
    PWDTRIM2='$(pwd | sed -E -e "s|^$HOME|~|" -e '\''s|^([^/]*/).*([^/]*/[^/]*/)|\1..\2|'\'')'
    PS1="${PROMPT_PRE}${PWDTRIM2}${PROMPT_POST}"

PWDTRIM1 이 스택오버플로 버전이고 PWDTRIM2 가 수정된 버전이다.

스크립트의 전체 구조를 보면, ① 먼저 pwd 명령으로 현재 작업 디렉토리 경로를 받아온 다음, ② sed로 $HOME 디렉토리 패턴을 물결(~)로 바꾸고, ③ 이어서 sed로 처음 하나의 디렉토리와 마지막 두개의 디렉토리 경로를 제외한 부분을 쩜쩜(..) 으로 바꾸어준다.

③ 단계가 복잡하니 이것만 자세히 분석해본다.

    PWDTRIM2='$(pwd | sed -E -e "s|^$HOME|~|" -e '\''s|^([^/]*/).*([^/]*/[^/]*/)|\1..\2|'\'')'

빨갛게 표시한 부분 좌우에 '\' 등 외따옴표로 묶인 것들은 escape를 위해 넣은 것들이다. 위의 sed 명령어에 쓰인 패턴매칭 크게 네 부분으로 나눌 수 있다.

^([^/]*/)
슬래시(/) 문자를 제외한 모든 문자 0개 이상으로 이루어진 문자열로 시작하는 패턴을 Back Reference로 구성하여 \1 로 저장. 이 패턴은 처음에 슬래시 문자가 나왔다가 다시 등장하거나, 슬래시 문자가 없다가 등장할 경우 패턴매칭이 끝나기 때문에 첫 번째 디렉토리 경로로 볼 수 있다.
.*
첫 번째 매칭 이후에 나오는 모든 문자들의 패턴. 뒤에 나올 마지막 2개 디렉토리 패턴은 해당 패턴이 가져가므로, 처음 하나 ~ 나중 두개 디렉토리 경로에서 중간 부분이라고 볼 수 있다.
([^/]*/[^/]*/)
[^/]* '슬래시(/)문자를 제외한 모든문자 0개 이상으로 이루어진 문자열' 이후에
/ '슬래시(/)문자'가 나오고
[^/]* 그리고 이어서 '슬래시(/)문자를 제외한 모든 문자 0개 이상으로 이루어진 문자열'이 등장.
/ 이어서 마지막으로 '슬래시(/)문자'가 나온다.
종합해 보면 마지막 2개의 디렉토리를 의미한다. 그리고 이 패턴은 Back Reference로서 /2 에 저장된다.
\1..\2
Back Reference 1번은 작업 디렉토리 경로에서 첫 번째 디렉토리이고, Back Reference 2번은 작업 디렉토리에서 마지막 두 개의 디렉토리이다. 이들 가운데 쩜쩜(..)을 넣도록 하여 문자열을 대치한다.