bzip2   :  gzip 보다 압축률이 높아 데이터를 더 작게 만들 수 있는 방식

사용법  

bzip2 로 파일 압축

$ bzip2 ps.txt
$ ls
.... ps.txt.bz2

 

압축한 파일 복원 ( -d )

$ bzip2 -d ps.txt.bz2

tar 와 bzip2 조합

아카이브 + 압축 ( j )

$ tar cfj dir1.tar.bz2 dir1

  - gzip으로 압축할때는  z 를 사용

 

xz  :  bz2 보다 압축률이 높아 높은 압축률이 필요한 상황에 적합

tar 와 xz 조합

아카이브 + 압축 ( J )

$ tar cJf dir1.tar.xz dir1

 

기본적인 사용방식

파일압축

gzip <압축할 파일>

 

명령어로 압축

(ps.txt 라는 파일이 있다고 가정)

$ gzip ps.txt
$ ls
... ps.txt.gz

 - 이때 압축에 사용된 원본 파일은 자동으 삭제됨

 

압축 파일 복원 ( -d )

$ gzip -d ps.txt.gz

 

표준 출력에 gzip 파일 출력하기 ( -c : 바이너리 데이터 출력 ) 

$ gzip -c ps.txt > ps_test.txt.gz

  - 이 방식은 파이프나 리다이렉션 용도로 사용

 

tar 와 gzip 조합하기

아카이브 파일 만들기 → 아카이브 파일 압축하기 를 tar 명령어로 한번에 가능

 >>> 옵션 z : gzip을 사용해 압축

파일 압축 ( czf )

$ tar czf dir1.tar.gz dir1
$ ls
.........  ps_test.txt.gz ...
dir1       dir1.tar.gz    ......

 

파일 복원 ( xzf )

$ tar xzf dir1.tar.gz

아카이브 와 압축

아카이브 : 여러개의 파일이나 디렉터리를 모아서 파일 하나로 만드는 것

압축 : 파일의 크기를 줄이는 것

 

tar 명령어

괄호 확장 명령어 팁!

{시작숫자..끝숫자}

$ touch dir1/file-{1..5}.txt
$ ls dir1
file-1.txt file-2.txt file-3.txt file-4.txt file-5.txt

$ echo {a..e}.txt
a.txt b.txt c.txt d.txt e.txt

$ echo sample.{txt,log,dat}
sample.txt sample.log sample.dat

 

tar 사용방법

$ tar cf <아카이브 파일 이름> <아카이브로 묶을 파일 경로>

 - c : create

 - f : file

 - tar 에서 옵션을 지정할 때에 하이픈(-) 을 붙여도 되고 안 붙여도 된다.

 

아카이브 파일 만들기 ( cf )

$ tar cf dir1.tar dir1

 

아카이브한 파일 내용 확인하기 ( tf )

$ tar tf dir1.tar
dir1/
dir1/file-5.txt
dir1/file-4.txt
dir1/file-3.txt
dir1/file-2.txt
dir1/file-1.txt

 

아카이브 해제하기 ( xf )

$ rm -rf dir1
$ tar xf dir1.tar
$ ls dir1
dir1/file-5.txt
dir1/file-4.txt
dir1/file-3.txt
dir1/file-2.txt
dir1/file-1.txt

 

옵션 v

 

파일 작성시 사용 cvf  : 아카이브 대상이 되는 파일 목록을 출력

$ tar cvf dir1.tar dir1
a dir1
a dir1/file-5.txt
a dir1/file-4.txt
a dir1/file-3.txt
a dir1/file-2.txt
a dir1/file-1.txt

 

파일 내용 확인시 사용 tvf : ls -a 와 같이 파일의 상세 정보 출력

$ tar tvf dir1.tar
drwxr-xr-x  0 joey   staff       0  4 12 15:36 dir1/
-rw-r--r--  0 joey   staff       0  4 12 15:36 dir1/file-5.txt
-rw-r--r--  0 joey   staff       0  4 12 15:36 dir1/file-4.txt
-rw-r--r--  0 joey   staff       0  4 12 15:36 dir1/file-3.txt
-rw-r--r--  0 joey   staff       0  4 12 15:36 dir1/file-2.txt
-rw-r--r--  0 joey   staff       0  4 12 15:36 dir1/file-1.txt

 

※ tar 은 파일의 권한, 소유자, 타임스탬프 같은 파일의 속성을 유지 한채로 아카이브함

                → 슈퍼 사용자 권한으로 백업에 사용 가능

셸 스크립트 동작 방식

많은 파일 속에서 특정문자열을 검색

 

사용되는 명령어

xargs

- 표준 입력으로 인자의 리스트를 받는 명령어

- 주로 find,  grep 과 조합을 하여 많은 파일에서 문자열을 검색하는 용도로 사용

- xargs < 실행하고 싶은 명령어> 방식

- < 실행하고 싶은 명령어> 가 표준입력으로 전달 받은 리스트를 인자로 실행

$ find . -type f -name '*.txt' | xargs ls -l

 - txt 타입의 파일 목록을 출력 →  출력된 리스트를 인자로 받아 실행

 

스크립트 예시

#!/bin/bash

pattern=$1
find . -type f | xargs grep "$pattern" 

 

위의 스크립트의 단점은

- find 에서 한 개의 결과가 나오면 파일이 이름이 출력이 되지 않는 다는 점 →  H 옵션 필요

- 파일에서 "pattern" 을 찾은 위치를 알 수 없다는 점  → n 옵션 필요

 

#!/bin/bash

pattern=$1
find . -type f | xargs grep  -nH "$pattern" 

 

좀 더 개선을 해보자

이 스크립트를 매번 검색할 디렉터리로 가서 실행해야하는 불편 → 디렉터리 지정 추가

검색하는 파일의 타입이 고정되어 있다는 불편함 → 파일타입 지정 추가

 

findgrep.sh

#!/bin/bash

pattern=$1
directory=$2
filetype=$3

if [ -z "$directory" ]; then
   directory='.'
fi

if [ -z "$filetype" ]; then
  filetype'*'
fi

find "$directory"  -type f -name "$filetype" | xargs grep  -nH "$pattern" 

 

사용 예시

$ findgrep.sh ldk "home" '*.txt'

 

 

도움말 / 사용법 표시

아래 코드를 findgrep.sh 상단에 추가

usage()
{
    #  셸 스크립트의 파일 이름을 취득
    local script_name=$(basename "$0")
    
    #도움말 표시
    cat << END

    Usage : $ script_name PATTERN [PATH] [NAME_PATTERN]
    Find file in currernt directory recursively, and print lines which match PATTERN

        PATH                        find file in PATH directory, instead of current directory
        NAME_PATTERN    specify name pattern to find file

    Examples:
        $ script_name return
        $ script_name return ~ '*.txt'
   
    END
}

if [ "$#" -eq 0 ]; then
    usage
    exit 1
fi

.... 코드

 

- cat << : here document 라고 하여 여러 행의 텍스트를 셸 스크립트에서 그대로 기술 하고 싶을 때 사용

 

에러 표시

......

# 검색 디렉토리가 존재 하지 않을 때 에러 메세지 출력하고 종료
if [ ! -d "$directory" ]; then
    echo "$0: ${directory} : No such directory" 1>&2
    exit 2
fi

 

 

최종 파일

#!/bin/bash

# 사용 방법
usage()
{
    #  셸 스크립트의 파일 이름을 취득
    local script_name=$(basename "$0")
    
    #도움말 표시
    cat << END

    Usage : $ script_name PATTERN [PATH] [NAME_PATTERN]
    Find file in currernt directory recursively, and print lines which match PATTERN

        PATH                        find file in PATH directory, instead of current directory
        NAME_PATTERN    specify name pattern to find file

    Examples:
        $ script_name return
        $ script_name return ~ '*.txt'
   
    END
}

if [ "$#" -eq 0 ]; then
    usage
    exit 1
fi

# 검색 함수 
pattern=$1
directory=$2
filetype=$3

if [ -z "$directory" ]; then
   directory='.'
fi

if [ -z "$filetype" ]; then
  filetype'*'
fi

# 검색 디렉토리가 존재 하지 않을 때 에러 메세지 출력하고 종료
if [ ! -d "$directory" ]; then
    echo "$0: ${directory} : No such directory" 1>&2
    exit 2
fi

find "$directory"  -type f -name "$filetype" | xargs grep  -nH "$pattern" 

셸 스크립트 동작 방식

1.  지정한 디렉터리의 모든 파일과 디렉터리를 출력하는 셸 스크립트 작성

 

작성 팁

1. 먼저 작고 간단한 기능부터 구현

2. 전체적인 흐름을 먼저 작성한 뒤 조금씩 구현

 

#!/bin/bash

# 함수 정의: 주어진 경로에 대한 파일 및 디렉터리 목록을 재귀적으로 출력
list_recursive() {

     local filepath=$1        # 첫 번째 인자로 받은 파일 경로를 지역 변수에 저장
     local indent=$2         # 두 번째 인자로 받은 들여쓰기 값을 지역 변수에 저장
     
     # 들여쓰기를 적용하고 파일 이름만 추출하여 출력
     echo "${indent}${filepath##*/}"
     
     # filepath 가 디렉터리인지 확인합니다.
     # 디렉터리라면 그 안의 항목들에 대해 루프를 실행
     if [ -d "$filepath" ]; then
         
         local fname    # 현재 처리 중인 파일 또는 디렉터리의 이름을 저장할 지역 변수
         
         for fname in $(ls $filepath) # 디렉터리 내의 각 항목에 대해 반복
         do
              # fname 이 디렉터리라면 재귀적으로 list_recursive 를 호출          
              list_recursive "${filepath}/${fname}" "${indent} "
         done
     fi
}

# 스크립트 실행의 시작점: 첫 번째 인자로 받은 경로를 기준으로 함수를 호출
list_recursive "$1" ""

+ Recent posts