bash script2023. 4. 7. 17:38

 

반달가면 이글루에서 백업 - http://bahndal.egloos.com/538266

 

sort 명령에 별다른 옵션을 주지 않으면 행 전체를 기준으로 정렬하게 되는데, 옵션을 추가해서 특정 항목을 기준으로 정렬을 할 수 있다.

아래의 예시를 보자.

# my_list.txt 내용 확인
cat my_list.txt
strawberry 46
mango 134
apple 33

# my_list.txt 내용 정렬
cat my_list.txt | sort
apple 33
mango 134
strawberry 46

아무런 옵션을 주지 않으면 행 전체를 문자열로 간주하고 정렬한다. 따라서 my_list.txt에서 a로 시작되는 행이 가장 먼저 출력되고 이후 알파벳 순으로 정렬되었다.
 
위의 예시에서 두번째 항목에 있는 수자를 기준으로 가장 큰 수부터 출력되도록 정렬하려면, 몇가지 옵션을 추가해 주어야 한다.

# 2번째 항목 기준(-k 2), 수자로 간주하여 정렬(-g), 제일 큰 수부터(-r)
cat my_list.txt | sort -k 2 -g -r
mango 134
strawberry 46
apple 33

-k 옵션으로 정렬 기준이 되는 항목을 지정한다. 항목 구분은 공백(space) 또는 탭(tab)이다. 위의 예시처럼 -k 2 이렇게 옵션을 주면 2번째 항목을 기준으로 잡게 된다. 그 외에 해당 항목을 문자열이 아니라 수자로 간주하기 위해 -g 옵션을, 정렬 순서를 바꾸기 위해 -r 옵션을 추가했다. (-g, -r 옵션에 대한 내용은 이전 게시물을 참고하자. 여기로)

항목 구분자(field separator)가 문자일 경우엔 어떻게 할까? 아래의 예시를 보자.

cat my_list2.txt
strawberry:46
mango:134
apple:33

my_list2.txt 파일은 구분자가 콜론(:)이다. 이 경우엔 정렬을 할 때 -t 옵션으로 구분자를 지정해 주면 된다.

# 콜론을 구분자로 사용(-t ":")
cat my_list2.txt | sort -t ":" -k 2 -g -r
mango:134
strawberry:46
apple:33

728x90
Posted by 반달가면
bash script2023. 4. 7. 17:31

 

반달가면 이글루에서 백업 - http://bahndal.egloos.com/535211

 

bash 스크립트에서 함수(function)는 특정 작업을 반복적으로 수행해야 할 때 매우 요긴한데, CPU 부하가 많이 걸리는 작업을 함수로 구현했을 경우 - 두어가지 유의할 점만 신경 쓰면 - 백그라운드로 여러개를 동시에 실행시켜서 소요 시간을 단축시킬 수 있다. (함수에 대한 기본적인 내용은 이전 게시물을 참고하자.)

아래의 간단한 예시를 보면서 감을 잡아 보자. ~/dir_1, ~/dir_2 디렉토리에서 txt 파일을 골라서 내용중에 문자열 "abcd"가 포함되어 있는지 확인하고, 만약 있으면 해당 파일명을 출력하는 스크립트이다.

# function: search_abcd [디렉토리] [문자열]
function search_string(){
  # 첫번째 인자($1)로 받은 디렉토리로 이동
  cd $1
  # 해당 디렉토리에서 .txt로 끝나는 파일에 대해 문자열(두번째 인자, $2) 포함 여부 확인
  for file in `ls | grep "\.txt$"`
  do
    # 파일에 특정 문자열($2)이 포함되어 있는 행의 수 구하기
    str_check=`cat $file | grep "$2" | wc -l`
    # 만약 1개 이상의 행이 해당 문자열을 포함하고 있다면 파일명 출력
    if [[ $str_check -ge 1 ]]
    then echo "$1 디렉토리에 있는 $file에 문자열 $2가 포함되어 있습니다."
    fi
  done
}

# main
# ~/dir1 디렉토리에 대해 문자열 검색
search_string ~/dir1 abcd
# ~/dir2 디렉토리에 대해 문자열 검색
search_string ~/dir2 abcd

자, 위의 예시를 보면 search_string 함수를 이용해서 ~/dir1 디렉토리에 대해 작업을 한 후에 ~/dir2 디렉토리에 대해 작업을 한다. 두 작업은 서로 독립적이므로, 함수를 백그라운드로 실행하면 두 작업을 동시에 진행할 수 있다.

단, 그렇게 하려면 유의해야 할 점이 있다. 함수 내부에서 사용하는 변수를 지역변수(local variable)로 선언해 주어야 한다. 두 함수가 동시에 실행되므로 같은 이름의 변수를 두개의 함수에서 동시에 사용하려면 반드시 함수 내부에서만 의미가 있도록 해 주어야 하는 것이다. 지역변수라고 명시되지 않은 변수는 기본적으로 전역변수(global variable)로 간주되므로 반드시 지역변수 선언을 해 주자.

또 한가지 생각해야 할 점은, 함수를 백그라운드로 실행했기 때문에 스크립트가 종료되었다고 해서 작업이 종료된 것을 의미하지 않는다는 것이다. 함수의 시작과 종료를 알려주는 내용을 출력하면 좀 더 친절한 스크립트가 된다.

위의 두가지 사항을 고려해서 스크립트를 고치면 아래와 같이 된다.

# function: search_abcd [디렉토리] [문자열]
function search_string(){
  # 지역변수(local variable) 선언
  local file
  local str_check
  # 함수 시작 메세지 출력
  echo "[search_string() 시작] 디렉토리 $1, 문자열 $2"
  # 첫번째 인자($1)로 받은 디렉토리로 이동
  cd $1
  # 해당 디렉토리에서 .txt로 끝나는 파일에 대해 문자열(두번째 인자, $2) 포함 여부 확인
  for file in `ls | grep "\.txt$"`
  do
    # 파일에 특정 문자열($2)이 포함되어 있는 행의 수 구하기
    str_check=`cat $file | grep "$2" | wc -l`
    # 만약 1개 이상의 행이 해당 문자열을 포함하고 있다면 파일명 출력
    if [[ $str_check -ge 1 ]]
    then echo "$1 디렉토리에 있는 $file에 문자열 $2가 포함되어 있습니다."
    fi
  done
  # 함수 종료 메세지 출력
  echo "[search_string() 종료] 디렉토리 $1, 문자열 $2"
}

# main
# ~/dir1 디렉토리에 대해 문자열 검색(백그라운드)
search_string ~/dir1 abcd &
# ~/dir2 디렉토리에 대해 문자열 검색(백그라운드)
search_string ~/dir2 abcd &
# 안내 메세지 출력
echo "작업이 아직 종료된 것이 아닙니다. 각 디렉토리에 대한 작업 종료 메세지가 나올 때까지 기다려 주세요."

거의 모든 PC가 멀티코어 CPU를 장착하고 있기 때문에, 서로 독립적인 다수의 반복작업을 해야 될 경우 함수로 구현하고 백그라운드로 실행하면 훨씬 더 빠르게 결과를 얻을 수 있다.

 

 

728x90
Posted by 반달가면
bash script2023. 4. 7. 17:27

 

반달가면 이글루에서 백업 - http://bahndal.egloos.com/533550

 

find 명령을 이용한 파일/디렉토리 검색은 매우 편리하지만, 검색을 수행하는 위치에 디렉토리와 파일 수가 상당히 많을 경우 속도가 꽤 느려지기도 한다. (find 명령의 기본적인 사용법은 이전 게시물을 참고하자. 여기로)

예를 들어 NFS로 연결된 디렉토리인데 파일이 수천개가 있고 여기서 find 명령을 반복적으로 수행해야 할 경우엔 의외로 시간이 상당히 소요될 수도 있다.

아래의 예시를 보자. file_list.txt 파일에 있는 파일 목록을 보고 ~/files 디렉토리에 같은 이름의 파일이 있는지 검색하는 경우이다. file_list.txt 파일의 내용은 아래와 같이 생겼다고 하자.

# file_list.txt 내용 확인
cat file_list.txt
my_file1.dat
my_file2.dat
...

이제 for 반복문을 이용해서 ~/files 디렉토리 안에 my_file1.dat 등 목록 파일에 저장된 파일명과 일치하는 것들이 있는지 확인한다. 색인 없이 그냥 만든 스크립트는 아래와 같다.

for file in `cat file_list.txt`
do
  # find 명령과 grep 명령으로 $file 변수값에 제시된 문자열과 일치하는 파일명 검색
  file_chk=`find ~/files -type f | grep "/$file$" | wc -l`
  if [[ $file_chk -ge 1 ]]
    then echo "~/files 디렉토리 하위에서 $file 파일을 발견! (일치하는 파일 개수: $file_chk)"
  fi
done

위의 예시에서 file_list.txt에 포함된 파일명이 100개 정도 되고, ~/files 디렉토리가 NFS로 연결되어 있으면서 안에 있는 파일이 수천개가 되면 위의 스크립트는 생각보다 시간이 꽤 걸린다.

이런 문제를 해결하기 위해 리눅스에서 기본적으로 제공하는 램(RAM) 디스크 영역인 /dev/shm 디렉토리에 임시로 색인을 만들어 보자. (/dev/shm 디렉토리에 대한 내용은 이전 게시물을 참고하자. 여기로)

/dev/shm 디렉토리에 mktemp 명령으로 임시 디렉토리를 만들고 그 안에 색인을 저장하자. (mktemp 명령에 대한 내용은 이전 게시물을 참고하자. 여기로)

이제 find 명령으로 색인을 만들고, 실제 검색할 때는 색인 파일을 cat 명령으로 열어서 검색하면 된다.

아래의 스크립트와 같은 형태로 만들면 되겠다.

# 램디스크 영역(/dev/shm)에 임시 디렉토리 만들기
tmp_dir=`mktemp -d /dev/shm/index_dir_XXXX`

# 색인 파일 file_index.idx 생성
find ~/files -type f > $tmp_dir/file_index.idx
# find 명령 대신 색인 파일에 대한 cat 명령으로 검색 수행
for file in `cat file_list.txt`
do
  # 색인 파일에서 $file 변수값에 제시된 문자열과 일치하는 파일명 검색
  file_chk=`cat $tmp_dir/file_index.idx | grep "/$file$" | wc -l`
  if [[ $file_chk -ge 1 ]]
    then echo "~/files 디렉토리 하위에서 $file 파일을 발견! (일치하는 파일 개수: $file_chk)"
  fi  
done
# 검색 종료. 임시 디렉토리 삭제
rm -r $tmp_dir

특정 디렉토리에 대해서 find 명령을 이용한 반복적인 검색을 해야 할 경우 위와 같은 방식을 사용하면 속도가 대폭 향상된다.

 

 

728x90
Posted by 반달가면
괜찮은_프리웨어2023. 4. 7. 14:46


반달가면 이글루에서 백업 - 
http://bahndal.egloos.com/440109

 

UNetbootin은 리눅스 ISO이미지를 USB 메모리에 옮기고 부팅이 가능하게 만들어 주는 프로그램이다. 윈도우 이미지는 지원하지 않는다. 윈도우를 USB로 옮기려면 이전에 게시한 WinToBootic을 이용하면 되겠다. 

한글을 지원하지 않지만 사용법이 워낙에 간단하기 때문에 크게 문제가 되진 않을 것 같다.

잘 알려진 리눅스 배포판은 대부분 지원한다.
 
Ubuntu 및 변종 (Xubuntu, Lubuntu 등)
Fedora
CentOS
OpenSUSE
Linux Mint
Debian

그 외에도 다수의 배포판을 지원하고 FreeBSD, FreeDOS 등 리눅스 외에 다른 OS나 시스템 복원용 부팅CD도 지원한다. 상세한 내역은 UNetBootin 홈페이지(http://unetbootin.sourceforge.net/)를 참조하자.

 


UNetbootin을 실행하면 ISO 이미지의 출처를 선택하게 된다.  배포판(Distribution)과 디스크이미지(Diskimage) 두가지다.

배포판(Distribution) 항목은 원하는 리눅스 버전을 선택하고 UNetbootin에서 자동으로 이미지를 다운로드한 후 USB 메모리에 옮기는 것이고, 디스크이미지(Diskimage) 항목은 직접 받아 놓은 ISO 이미지 파일을 선택해서 USB 메로리로 옯기는 것이다.

배포판 또는 ISO 이미지 선택하고 USB 메모리가 할당된 드라이브 확인한 후 OK 버튼 누르면 된다.

USB 메모리의 파일시스템이 FAT32이어야 한다는 점에 유의하자. NTFS로 포맷한 USB 메모리일 경우 제대로 부팅이 되지 않는다. (EFI 부팅은 어쩌면 좀 다를 수도 있겠는데, 시험해 보지 않아서 잘 모르겠다.)

728x90
Posted by 반달가면