2015/05/17

bash 사용법 (Update:20160204)

http://kiros33.blog.me/130147148013



Revision History
2015/02/12 12:48:33 - 리눅스 환경 변수 사용법 링크 추가
2015/02/26 16:12:28 - Bash 익히기 관련 링크 추가
2015/03/15 23:41:42 - Bash에서 전달인자를 배열로 저장 활용하는 방법
2015/03/16 02:15:30 - 파일이름에서 이름과 확장자를 분리하는 방법
2015/05/19 23:47:39 - Bash에서 전달인자를 배열로 저장 활용하는 방법 #2, 특정 위치부터 반복하는 방법
2015/11/22 14:08:34 - 아포스트로피(apostrophe)(') 중복 사용, Single quotation
2016/01/29 21:50:08 - 파일이름에서 이름과 확장자를 분리하는 방법 내용 추가
2016/02/04 01:16:38 - 함수 선언 및 조회 하는 방법

Reference Page
  

ADD: 2015/02/26 16:12:28

이재홍님의 가장 빨리 만나는 Docker 내용을 보다가 4장 Docker 이미지 생성하기의 Bash 익히기 부분이 마음에 들어서 관련 링크로 추가했습니다.


사용되는 명령 샘플과 동일한 결과를 얻기 위해서는 아래 글을 참조해서 디렉토리와 파일을 생성하시면 됩니다.

* 추가로 파일을 생성합니다.
cd ${TEST_ROOT}/dir1
touch 00.a.mp3
touch 00.a.mp4
touch 00.a.mp5
touch 00.a.mp8
touch 00.b.mp3
touch 00.c.mp3
touch 00.d.mp3
touch 00.a.mp3
touch 00.s.mp3
touch 00.a.mp3
touch 00.z.mp3


>>>>> 명령어 확장, 파일이름 다중 지정
명령어 확장을 통한 파일 다중 지정(Multiple file assign)dms 중괄호 확장 (Brace Expansion) 과 대괄호 확장 (Bracket Expansion) 으로 가능합니다.

중괄호 확장은 중첩될 수 있습니다. (Brace  expansions  may  be nested)

확장할 수 없는 표현식은 파일이름으로 인식합니다. 따라서 $ ls -d *.a.mp{3} 명령을 실행하면 파일을 찾을 수 없다는 오류가 발생합니다.
  
cd ${TEST_ROOT}/dir1
ls -d *.a.mp[358]
00.a.mp3        00.a.mp5        00.a.mp8
ls -d *.a.mp{3,5,8}
00.a.mp3        00.a.mp5        00.a.mp8
ls -d *.a.mp{3}
ls: *.a.mp{3}: No such file or directory
ls -d *.a.mp{1..8}
ls: *.a.mp1: No such file or directory
ls: *.a.mp2: No such file or directory
ls: *.a.mp6: No such file or directory
ls: *.a.mp7: No such file or directory
00.a.mp3        00.a.mp4        00.a.mp5        00.a.mp8
$ ls -d *.a.mp{1..8} 2> /dev/null
00.a.mp3        00.a.mp4        00.a.mp5        00.a.mp8
ls -d 00.{a..s}.mp3 2> /dev/null
00.a.mp3        00.b.mp3        00.c.mp3        00.d.mp3        00.s.mp3
ls 00.{{a,b}.mp3,{a,b}.mp4} 2> /dev/null
00.a.mp3        00.a.mp4        00.b.mp3


>>>>> 명령어를 파이프로 받아서 실행
find 와 awk 를 사용해서 명령어 문자열을 생성하고 그 결과를 파이프로 전달해서 실행하는 방법
  
find . -maxdepth 1 -type d | awk -F '[\/\.]' 'NR>=2 {print "cp " $3"*.{mp4,m4a,mkv,flv,f4v,wmv,asf,mov,avi} \""$0"\""}' | bash 2> /dev/null

 
>>>>> Bash에서 전달인자를 배열로 저장 활용하는 방법
전달인자를 직접 반복하는 것과 배열로 저장해서 배열을 반복하는 방식으로 예제를 작성해봤습니다.
function arg_test() {
   args=("$@")
   echo ${args[0]} ${args[1]} ${args[2]} 
   
   for a in $@
   do
     echo "arg: $a "
   done

   for b in ${args[@]}
   do
     echo "arg: $b "
   done
}
for b in ${args[@]} 를 사용하는 경우 공백이 포함된 값을 제대로 인식하지 못합니다. 필요한 경우 for b in "${args[@]}"  처럼 문자열로 감싸면 됩니다.

실행하면 두 번 반복됩니다.
arg_test a b c d e
a b c
arg: a 
arg: b 
arg: c 
arg: d 
arg: e 
arg: a 
arg: b 
arg: c 
arg: d 
arg: e 
  

>>>>> 2015/05/19 23:47:39 - Bash에서 전달인자를 배열로 저장 활용하는 방법 #2, 특정 위치부터 반복하는 방법
  
테스트 코드
function test() {
   for i in ${@:3} ; do echo $i; done

   args=("${@:3}")

   for f in "${args[@]}"
   do
      echo run ${f}
   done

   for i in ${@:2:2} ; do echo $i; done
}
 
실행 예제
test 1 2 3 4 5 6
3
4
5
6
run 3
run 4
run 5
run 6
2
3

pdf 메타 설정 함수
function tag2pdf() {
   files=("${@:3}")

   for f in "${files[@]}"
   do
      exiftool -overwrite_original -Title="$(basename ${f%.*})" -Author="${1} ${2}" -Subject="${1}" "${f}";
   done
}

 
>>>>> 
파일이름에서 이름과 확장자를 분리하는 방법

1) 전체 경로에서 파일 이름만 분리
2) 분리된 파일 이름에서 확장자와 이름을 분리
ls img\ 2.png 
img 2.png
filepath=$(basename img\ 2.png)
echo $filepath
img 2.png
fileext="${filepath##*.}"
echo $fileext 
png
filename="${filepath%.*}"
echo $filename
img 2
  
basename 대신 filepath="${fullpath##*/}" 명령도 사용 가능합니다.
  
2016/01/29 21:50:08 - 파일이름에서 이름과 확장자를 분리하는 방법 내용 추가
FILE="example.tar.gz"
echo "${FILE%%.*}"
example
echo "${FILE%.*}"
example.tar
echo "${FILE#*.}"
tar.gz
echo "${FILE##*.}"
gz
  
 
>>>>> 아포스트로피(
apostrophe)(') 중복 사용

음 이걸 Single quotation 이라고 부르는게 맞을꺼 같기도 하고 -_-;;; 헤깔림

간혹 ' 문자를 중복사용하고 싶은 경우 bash의 문자열 연결을 사용해서 처리 할 수 있습니다.

a'b 라는 문자열을 나타내기 위해서는 'a' 와 "'" 그리고 'b' 라는 3개를 합치면 됩니다. 공백없이 붙여야 인식되요~
echo 'a'"'"'b'
a'b
   
bash내에서 echo 사용시  ' 문자를 이스케이프(Escape)하기 위해서는 \기호를 추가하면 됩니다.
bash -c 'echo a'"\'"'b'
a'b
  

 >>>>> 2016/02/04 01:16:38 - 함수 선언 및 조회 하는 방법

종종 함수를 선언해서 사용하면 복잡한 문제를 쉽게 해결 할 수 있습니다.
헌데 의외로 함수 기능을 모르시는 분이 많아 기록합니다.

함수 선언
function exifdel() {
        if [ $# -lt 2 ]; then
                echo usage: ${FUNCNAME[0]} "\"UserComment\"" "\"${HOME}/file.ext\""
                return 1
        fi

        cp -v "${2}" "${2%.*}.exifdel.${2##*.}"
        exiftool -json "${2}" | grep -v "${1}" > "${2%.*}.json"
        exiftool -overwrite_original -all= "${2}"
        exiftool -overwrite_original -json="${2%.*}.json" "${2}"
        rm -v "${2%.*}.json"
}
type exifdel 
   
확인은 declare 명령으로도 가능합니다.
declare -f exifdel
exifdel () 
    if [ $# -lt 2 ]; then
        echo usage: ${FUNCNAME[0]} "\"UserComment\"" "\"${HOME}/file.ext\"";
        return 1;
    fi;
    cp -v "${2}" "${2%.*}.exifdel.${2##*.}";
    exiftool -json "${2}" | grep -v "${1}" > "${2%.*}.json";
    exiftool -overwrite_original -all= "${2}";
    exiftool -overwrite_original -json="${2%.*}.json" "${2}";
    rm -v "${2%.*}.json"
}
  

   
아래는 오래된 항목

history
--------------------------------------------------------------------------------

to call 1st arg:
    $ echo !!:1
    $ echo !237:2

get the directory name only
    $ rsync /nas/a/x/y/foo/bar.txt root@server1:/dest/to/path
    $ rsync -a !!:1:h !!:2

get the file name only
    $ cp /path/to/logn/dir/foofilenameverylongfilename.txt /mnt/floppy
    $ cp !!:1:t !!:2

get and substitute
    $ scp user@server1:/path/to/alongdir1/file.txt user@server2:/dest
    $ scp !!:1:s/dir1/dir2 !!:2


bash pause command - under Linux / UNIX

--------------------------------------------------------------------------------
read -p "Press [Enter] key to start backup..."
#!/bin/bash
# init
function pause(){
   read -p "$*"
}
 
# ...
# call it
pause 'Press [Enter] key to continue...'
# rest of the script
# ...

검색: Bash Shell, 배쉬 배시 셀 쉘 셸, Bourne Again SHell, 본 어게인 셸, Bourne shell, sh, 본 쉘 셸 셀, 

댓글 없음:

댓글 쓰기