아래 문서 적극 참고

https://blog.gaerae.com/2015/01/bash-hello-world.html

 

Bash 입문자를 위한 핵심 요약 정리 (Shell Script)

 

blog.gaerae.com

 

 

파라미터가 정해진 개수만큼 들어왔는지 확인


if [ $# -ne 3 ]; then
    exit 1
fi
echo "3개 들어왔음"

 

파라미터가 제대로 들어왔으면 실행하고,

제대로 들어오지 않았으면 exit 1 하여 스크립트를 종료

(bash 종류에 따라 다르다고 함)

#!/bin/bash

INPUT=${1:?"no input"}
echo "input is ${INPUT}"
< 실행 결과 >

eyeballs@eyeballs:~$ ./script.sh 
  ./a.sh: line 3: 1: no input

eyeballs@eyeballs:~$ echo $?
  1

eyeballs@eyeballs:~$ ./script.sh eyeballs
  input is eyeballs

eyeballs@eyeballs:~$ echo $?
  0

 

 

스크립트 실행 중 에러가 생길 때(exit 번호가 0이 아니면)

곧바로 스크립트를 종료하도록 하려면 set -e 옵션을 추가

(참고 : https://eyeballs.tistory.com/451)

#!/bin/bash
set -e

cp /a/b/c /d/e/f

 

 

 

문자열을 자른 후 그 개수를 세는 방법


문자열이 "a-b-c-d-e" 라고 하자.

awk -F'-' '{print NF}'

위 명령어의 결과는 5

 

명령문의 결과를 변수에 넣는 방법


파라미터로 "a-b-c-d-e" 를 넣었다고 하자.

NUM=$(head $1 | awk -F'-' '{print NF}')
echo ${NUM}

NUM 에 5 값이 들어간다.

 

 

개행이 포함된 문자열을 개행을 기준으로 for 문 돌리기 + 문자열 잇기(concat)

list="aaa
bbb
ccc"

for element in ${list}
do
    echo ${element}
done

결과값으로
aaa
bbb
ccc
가 출력된다.
list="aaa
bbb
ccc"

for element in ${list}
do
    echo ${element} "입니다."
done

결과값으로
aaa 입니다.
bbb 입니다.
ccc 입니다.
가 출력된다.
list="aaa
bbb
ccc"

concat=""
for element in ${list}
do
    concat="${concat} ${element}"
done
echo ${concat}

결과값으로
aaa bbb ccc
가 출력된다.
문자열을 이을 때(concat)는, 위와 같이

concat="ab"
concat="${concat}cd"
결과 : abcd

이렇게 이어도 되지만, 
자바처럼 += 를 사용할 수 있다.

concat="ab"
concat+="cd"
echo ${concat} : abcd
for topic in $(hdfs dfs -ls /user/eyeballs/ | awk '{print $8}');
do 
    echo ${topic}
done

 

csv 의 헤더를 없애는 방법

sed -i 1d mycsv.csv

 

HDFS 내에 파일이 존재하는지 확인하는 방법


/my/hdfs/path 에 파일들이 존재하는지 확인해보자.
아래 스크립트에서 no result 가 뜨면 파일이 존재하지 않는 것이다.

EXIST=$(hdfs dfs -ls /my/hdfs/path 2>/dev/null || true)
if [[ -z ${EXIST} ]]; then
    echo "no result"
    exit 1
fi

참고 : https://eyeballs.tistory.com/319

 

현재, 4시간 전, 이틀 전 날짜의 year, month, day, hour 얻기

#!/bin/bash

echo "----현재 날짜----"
echo year : $(date +%Y)
echo month : $(date +%m)
echo day : $(date +%d)
echo hour : $(date +%H)
echo year_month : $(date +%Y-%m)
echo month.day : $(date +%m.%d)

echo "----4시간 전 날짜----"
echo year : $(date -d "4 hour ago" +%Y)
echo month : $(date -d "4 hour ago" +%m)
echo day : $(date -d "4 hour ago" +%d)
echo hour : $(date -d "4 hour ago" +%H)
echo year_month : $(date -d "4 hour ago" +%Y-%m)
echo month.day : $(date -d "4 hour ago" +%m.%d)

echo "----2일 전 날짜----"
echo year : $(date -d "2 day ago" +%Y)
echo month : $(date -d "2 day ago" +%m)
echo day : $(date -d "2 day ago" +%d)
echo hour : $(date -d "2 day ago" +%H)
echo year_month : $(date -d "2 day ago" +%Y-%m)
echo month.day : $(date -d "2 day ago" +%m.%d)

echo "----특정 날짜로부터 5일 전 날짜----"
DATE="1991-06-25"
echo year : $(date -d "${DATE} 5 day ago" +%Y)
echo month : $(date -d "${DATE} 5 day ago" +%m)
echo day : $(date -d "${DATE} 5 day ago" +%d)
echo hour : $(date -d "${DATE} 5 day ago" +%H)
echo year_month : $(date -d "${DATE} 5 day ago" +%Y-%m)
echo month.day : $(date -d "${DATE} 5 day ago" +%m.%d)

echo "----특정 날짜로부터 5일 후 날짜----"
DATE="1991-06-25"
echo year : $(date -d "${DATE} -5 day ago" +%Y)
echo month : $(date -d "${DATE} -5 day ago" +%m)
echo day : $(date -d "${DATE} -5 day ago" +%d)
echo hour : $(date -d "${DATE} -5 day ago" +%H)
echo year_month : $(date -d "${DATE} -5 day ago" +%Y-%m)
echo month.day : $(date -d "${DATE} -5 day ago" +%m.%d)

 

특정 날짜부터 특정 날짜까지 for 문 돌기

아래 코드에서 -d "2020.... " 를 제외하면, 'date' 에 의해 현재 날짜가 된다.

#! /bin/bash

START_DATE=$(date +"%Y-%m-%d" -d "2020-09-10")
END_DATE=$(date +"%Y-%m-%d" -d "2020-12-31")

for (( ; ; ))
do
    echo ${START_DATE}
    START_DATE=$(date +"%Y-%m-%d" -d "${START_DATE} + 1 day")
    if [ ${START_DATE} == ${END_DATE} ]
    then
        echo ${START_DATE}
        break
    fi
done
#! /bin/bash

DATE="20210101"
for i in $(seq 0 10)
do
    echo ${DATE}
    DATE=$(date +"%Y%m%d" -d "${DATE} + 1day")
done

 

 

어떤 스크립트가 잘 실행되었는지 확인하는 방법

스크립트의 가장 마지막에서 $? 를 확인하면 된다.


#!/bin/bash

cp /a/b/c /d/e/f
[ "$?" -eq 0 ] && echo "ran well"


#!/bin/bash

cp /a/b/c /d/e/f
[ $? -ne 0 ] && exit 1

echo "ran well"


#!/bin/bash

cp /a/b/c /d/e/f
if [[ $? -ne 0 ]]; then
    echo "ran wrong"
fi
echo "ran well"

 

카운터 (위 아래 코드는 같은 결과를 반환함)

#!/bin/bash

COUNTER=$1
while [ ${COUNTER} -ne $2 ]; do
    echo ${COUNTER}
    COUNTER=$((COUNTER+1))
done
#!/bin/bash

COUNTER=$1
while true; do
    echo ${COUNTER}
    COUNTER=$((COUNTER+1))
    if [[ ${COUNTER} -eq $2 ]]; then
        exit 0
    fi
done

 

숫자를 계속 증가시키는 seq 명령어도 사용 가능

-w 옵션을 붙이면 숫자 앞에 0을 자동으로 채워줌

#!/bin/bash

for a in $(seq -w 5 15)
do
    echo ${a}
done

 

seq는 -f 명령을 통해 원하는 자릿수만큼 앞에 0을 채울 수 있음

#세자리
> seq -f %03g 9 11
009
010
011

# 다섯자리
> seq -f %05g 9 11
00009
00010
00011

 

 

 

 

배열 사용하는 방법

아래 블로그에 아주 좋은 예제가 있다.

http://blog.redjini.com/282

배열(Array) : 선언하기

1
2
array_name_1=("value 1" "value 2" "value 3")
array_name_2=(1 2 3)

배열(Array) : 참조하기

1
2
3
4
5
6
7
8
9
array_name=("value 1" "value 2" "value 3")
 
echo "array_name[0]     = ${array_name[0]}"  #print array_name[0]
echo "array_name[2]     = ${array_name[2]}"  #print array_name[2]
echo "array_name[*]     = ${array_name[*]}"  #print array_name all item
echo "array_name[@]     = ${array_name[@]}"  #print array_name all item
echo "array_name index  = ${!array_name[@]}" #print array_name index number
echo "array_name size   = ${#array_name[@]}" #print array_name size
echo "array_name[0] size= ${#array_name[0]}" #print array_name[0] size

출력 결과

array_name[0]     = value 1
array_name[2]     = value 3
array_name[*]     = value 1 value 2 value 3
array_name[@]     = value 1 value 2 value 3
array_name index  = 0 1 2
array_name size   = 3
array_name[0] size= 7

배열(Array) : 크기 구하기

1
2
3
array_name_1=("value 1" "value 2" "value 3")
 
echo ${#array_name_1[@]}  #print "3"

배열(Array) : 출력하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
array_name=("value 1" "value 2" "value 3")
 
echo "array = ${array_name[@]}"
# 출력 결과
# array = value 1 value 2 value 3
 
printf "value = %s\n" "${array_name[@]}"
# 출력 결과
# value = value 1
# value = value 2
# value = value 3
 
for value in "${array_name[@]}"; do
    echo $value
done
# 출력 결과
# value 1
# value 2
# value 3
 
for (( i = 0 ; i < ${#array_name[@]} ; i++ )) ; do
    echo "value[$i] = ${array_name[$i]}"
done
# 출력 결과
# value[0] = value 1
# value[1] = value 2
# value[2] = value 3
 
for index in ${!array_name[*]} ; do
    printf "%4d: %s\n" "$index" "${array_name[$index]}"
done
# 출력 결과
#   0: value 1
#   1: value 2
#   2: value 3

 

 

실행되는 스크립트가 위치한 path 로 현재 dir 옮기기

cd $(dirname $0)

 

 

파일 크기 모두 더하고 gb, mb 로 표시하기

리눅스 du 명령어 결과의 경우

du --max-depth=1 . | awk '{n+=$1} END {printf "%.1fM bytes\n", n/1024/1024}'
hdfs 결과의 경우

hdfs dfs -du /my/path/ | awk '{n+=$1} END {printf "%.1fM bytes\n", n/1024/1024}'
hdfs dfs -du /my/path/ | awk '{n+=$1} END {printf "%.1fG bytes\n", n/1024/1024/1024}'

 

 

substring

${string 변수 이름:처음 시작 index:길이}

string='2022-01-12-eyeballs'
year=${string:0:4}
month=${string:5:2}
day=${string:8:2}
name=${string:11:9}

 

python 에 한 줄로 명령어 실행하는 방법

#!/bin/bash

python -c 'import json; print("Hello World!")'
val=$(python -c 'import json; print("eyeballs is awesome!")')

 

 

 

현재 위치에서의 폴더 개수

ls -l | grep ^d | wc -l


현재 위치에서의 파일 개수

ls -l | grep ^- | wc -l


현재 폴더의 하위 파일 개수

find . -type f | wc -l

 

 

 

if 문은 아래와 같이 사용함

if [ 조건 ]
then
  참일 때의 실행문
fi
예)

#!/bin/bash
if [ 1=1 ]
then
  echo "1은 1이다"
fi
exit 0

참고로 조건문의 대괄호 양쪽에는 공백이 무조건 있어야 함.

if [ 조건 ]
then
  참일 때의 실행문
else
  거짓일 때의 실행문
fi
예)

#!/bin/bash
if [ "eyeballs" = "eye" ]
then
  echo "참값"
else
  echo "거짓값"
fi
exit 0

조건문에 비교 연산자는 아래와 같음.

= : 양쪽이 같으면 참

!= : 양쪽이 다르면 참(양쪽이 같으면 거짓)

-n "문자열" : 문자열이 Null(빈 문자열)이 아니면 참 (문자열 길이가 0이 아니면 참)

-z "문자열" : 문자열이 Null(빈 문자열)이면 참 (문자열 길이가 0이면 참)

수식1 -eq 수식2 : 두 수식(혹은 변수)이 같으면 참

수식1 -ne 수식2 : 두 수식(혹은 변수)이 다르면 참

수식1 -gt 수식2 : 수식 1이 수식 2보다 크면 참(>)

수식1 -ge 수식2 : 수식 1이 수식 2보다 크거나 같으면 참(>=)

수식1 -lt 수식2 : 수식 1이 수식 2보다 작으면 참(<)

수식1 -le 수식2 : 수식 1이 수식 2보다 작거나 같으면 참(<=)

!수식 : 수식이 거짓이면 참 (수식에 거짓이 있나??)

-a : && 연산과 동일. and 연산

-o : || 연산과 동일. xor 연산

-d : 파일이 디렉터리라면 참

-e : 파일이 존재하면 참

-L : 파일이 심볼릭 링크면 참

-r : 파일이 읽기 가능하다면 참

-w : 파일이 쓰기 가능하다면 참

-x : 파일이 실행 가능하다면 참

-s : 파일 크기가 0보다 크다면 참

$# -ne 2 : 파라미터 개수($#)가 2개라면 참
파일1 -ef 파일2 : 파일1이 파일2와 같은 파일이라면 참

파일1 -nt 파일2 : 파일1이 파일2보다 최신파일이라면 참
파일1 -ot 파일2 : 파일1이 파일2보다 이전파일이라면 참

 

참고 https://eyeballs.tistory.com/319

 

 

cut 명령어 없이 문자열 자르는 방법

A="ABCDE"         
echo ${A:0:4}  # 결과 : ABCD
echo ${A:1:2}  # 결과 : BC

 

 

 

 

 

 

 

 

+ Recent posts