[Linux-vim] vim에디터 사용하기 5 - function (함수), jq(JSON 파싱), 다른 언어 활용
# 정리
** python3 : 사용자친화적인 언어지만 초기엔 불편한 부분들이 있어 개선되는 중이며, 현재 3버젼이 많이 쓰이고 있다.
** 함수를 만들어서 사용하는 이유 : 재사용성을 용이하게 하기 위해
(같은 기능을 여러번 사용할 때 편하라고 = 코딩을 덜하기 위해서(유지보수 포함) = 개발 시간을 줄이기 위해서 )
# otherlanguage - 다른 언어 가져오기
//($언어명 -c "명령문") 형태로 다른 언어를 가져와 사용할 수 있다.
- $python -c "print(3*5)"
//다른 언어의 명령문의 결과 값도 $( )안에 담아 변수에 넣을 수 있다.
<사실 효율적인 방법은 아니지만, 할 수 있다는 것을 아는게 중요!>
- $()를 이용해서 result 에 다른 언어의 결과를 넣은 것을 볼 수 있다.
- $($python -c "print(3*5)" ) - 파이썬 언어의 명령구문의 결과(15)를 값으로 가진다.
# function 함수
( 1. Basic )
//함수를 만들 때 염두해야 할 4가지 ( 인풋 있고 없고 / 리턴 있고 없고 )
- 쉘스크립트는 리턴 값이 텍스트 반환밖에 없다는 특징이 있다.
//쉘에는 함수만 블록{}이 있다.
//쉘스크립트함수는 타입이 없이 함수명이 바로온다.
//함수 콜 할때 ()를 붙이지 않는다. (ex. testFn() - X / testFn - O)
- 함수이름을 바로 변수에 할당하면 텍스트로 인식되며, 함수의 결과를 불러오려면 $( )안에 넣어야한다.
//return을 적지 않아도, 기본적으로 return이 들어있다.
- 쉘에서는 return 뒤에 내용이 리턴되는 것이 아니라, 함수 내의 출력문 전체의 결과 값이 리턴되는 것에 주의할 것
( 2. 변수 활용 )
//함수 안에서 외부 변수를 받아오거나 내부 변수를 활용할 수 있다.
//자바, 자바스크립트와 달리 함수 내부 (블록내부) 에 있는 변수를 밖에서도 사용할 수 있다.
- $local - 밖에서는 못쓰게 만드는 방법 >> 지역변수로 변경
( 3. 행렬 활용 )
//함수의 결과 값은 행렬로 들어오는 것이 아니라 텍스트로 들어온다.
- 함수 결과 값을 행렬로 하고 싶으면 밖에 ( )로 감싸줘야한다.
- 텍스트의 나열은 for in으로 출력해야하지만, 행렬로 만들면 전통적인 for문으로도 출력할 수 있다.
( 4. 위치 매개변수($1,$2..) 활용 )
//$( )로 감싸면 한 줄의 텍스트값으로 결과값이 모여서 나옴
#jq - json 파싱
//jq패키지를 추가로 설치해야 사용 가능하다.
- $sudo apt install -y jq
//JSON 형식으로 쓰여진 텍스트를 파싱할 때 사용한다.
- [] - 배열 (인덱스-값) , {} - 객체 (키-값)
- 나중에 레스트 컨트롤러에서 읽어온 값이 제이슨일 때 활용할 수 있다.
- Java의 Jackson 형식, JS의 object 형식과 같음
//Jq를 사용하는 2 가지 방법
** 웹페이지를 cat으로 읽어오게되고, cat외에도 head /tail등 다양한 변화가 가능해서 1번이 더 자주 사용됨.
- cat으로 읽어들인 텍스트를 jq로 처리하는 방법(뒷 내용 참조) : cat sh17temp2.json |jq '.[0].id'
- jq 단독으로 읽어오는 방법 : jq ".vo.id" sh17temp.json
//넘어온 데이터를 읽어내는 역할로 $cat 외에 $head / $tail 도 함께 활용할 수 있다.
- head 앞줄 읽기 / tail 뒷줄 읽기 (-숫자 : 읽는 줄 수 지정 옵션)
- 넘어온 데이터에 특정 위치의 줄이 제이슨일 때 같이 활용한다.
// . 은 ~안에 라는 뜻임을 기억하자.
//데이터 안의 특정 인덱스나 키 값을 활용하여 특정 값만 읽어올 수 있다.
- jq "." 파일명 : 파일 안 모든 값을 불러와줘
- jq ".vo" 파일명 : "vo"에 있는 내용을 불러와줘
- jq ".vo.id" 파일명 : "vo"가 가진 값 중 "id"값을 불러와줘
- jq ".arr" 파일명 : "arr"에 있는 내용을 불러와줘
- jq ".arr[1]" 파일명 : "arr" 배열 값 안에 1번 인덱스 값을 불러와줘
//curl과 jq를 혼합하여 웹상의 데이터를 읽어올 수 있다.
- $curl (-s옵션) 데이터 읽어올 때 통신 정보는 출력 안함
- $jq (-r옵션) 최종 값에 " "표시를 없애줘 (ex. "admin" >> admin)
* -r은 배열 데이터의 최종 키값으로 대응되는 최하위단의 데이터를 단독 출력할 때만 적용됨.
** python3 : 사용자친화적인 언어지만 초기엔 불편한 부분들이 있어 개선되는 중이며, 현재 3버젼이 많이 쓰이고 있다.
# otherlanguage - 다른 언어 가져오기
//($언어명 -c "명령문") 형태로 다른 언어를 가져와 사용할 수 있다.
- $python3 - 파이썬(3) 부르기 ; 파이썬(3) 언어 안으로 들어가겠다. ( >>>exit() 종료 함수 / >>>print() 출력 함수 )
- $python -c "print(3*5)"
//다른 언어의 명령문의 결과 값도 $( )안에 담아 변수에 넣을 수 있다.
<사실 효율적인 방법은 아니지만, 할 수 있다는 것을 아는게 중요!>
- $()를 이용해서 result 에 다른 언어의 결과를 넣은 것을 볼 수 있다.
- $($python -c "print(3*5)" ) - 파이썬 언어의 명령구문의 결과(15)를 값으로 가진다.
#!/bin/bash
clear
pwd
echo $0
echo "----------------------------"
x=3
y=5
echo $((x*y))
echo $(python -c "print($x*$y)")
result=$(python -c "print($x*$y)")
echo $result
exit 0
** 함수를 만들어서 사용하는 이유 : 재사용성을 용이하게 하기 위해
(같은 기능을 여러번 사용할 때 편하라고 = 코딩을 덜하기 위해서(유지보수 포함) = 개발 시간을 줄이기 위해서 )
# function 함수 - 1. Basic
//함수를 만들 때 염두해야 할 4가지 ( 인풋 있고 없고 / 리턴 있고 없고 )
- 쉘스크립트는 리턴 값이 텍스트 반환밖에 없다는 특징이 있다.
//쉘에는 함수만 블록{}이 있다.
//쉘스크립트함수는 타입이 없이 함수명이 바로온다.
//함수 콜 할때 ()를 붙이지 않는다. (ex. testFn() - X / testFn - O)
- 함수이름을 바로 변수에 할당하면 텍스트로 인식되며, 함수의 결과를 불러오려면 $( )안에 넣어야한다.
//return을 적지 않아도, 기본적으로 return이 들어있다.
- 쉘에서는 return 뒤에 내용이 리턴되는 것이 아니라, 함수 내의 출력문 전체의 결과 값이 리턴되는 것에 주의할 것
#!/bin/bash
clear
pwd
echo $0
echo "----------------------------"
testFn(){
echo "testFn()...a"
echo "testFn()...b"
#return exists evenif return wasn't written
}
#function call (testFn() >> X)
testFn
result=testFn
echo "return:"$result
result=$(testFn)
echo "return:"$result
exit 0
-------------------------------------------
# function 함수 - 2. 변수 활용
//함수 안에서 외부 변수를 받아오거나 내부 변수를 활용할 수 있다.
//자바, 자바스크립트와 달리 함수 내부 (블록내부) 에 있는 변수를 밖에서도 사용할 수 있다.
- $local - 밖에서는 못쓰게 만드는 방법 >> (아래 예문 참조) eng는 값이 안나오고 있다.
#!/bin/bash
clear
pwd
echo $0
echo "----------------------------"
name_product="NoteBook"
readonly NAME="kim"
testFn(){
echo "testFn()...a" $name_product
echo "testFn()...b" $NAME
kor=100
echo "testFn...c" $kor
local eng=99
echo "testFn()...d" $eng
#return
}
#function call
testFn
echo "----------------------------"
echo "name_product:"$name_product
echo "NAME"$NAME
echo "kor"$kor
echo "eng"$eng
#function call
result=$(testFn)
echo "return:"$result
exit 0
-------------------------------------------
# function 함수 - 3. 행렬 활용
//함수의 결과 값은 행렬로 들어오는 것이 아니라 텍스트로 들어온다.
- 함수 결과 값을 행렬로 하고 싶으면 밖에 ( )로 감싸줘야한다.
- 텍스트의 나열은 for in으로 출력해야하지만, 행렬로 만들면 전통적인 for문으로도 출력할 수 있다.
#!/bin/bash
clear
pwd
echo $0
echo "----------------------------"
score(){
echo 99 88 77
}
echo $(score)
str=$(score)
echo "str.length:"${#str}
for item in $(score)
do
echo $item
done
echo "----------------------------"
arr=($(score))
echo ${arr[@]}
echo "arr.length:"${#arr[@]}
echo ${arr[0]}
echo ${arr[1]}
echo ${arr[2]}
exit 0
-------------------------------------------
# function 함수 - 4. 위치 매개변수($1,$2..) 활용
//$( )로 감싸면 한 줄의 텍스트값으로 결과값이 모여서 나옴
//토탈 합산을 밖에서 하면 실행명령이 없어서 $1,$2,$3에 값이 없음
//seq 명령으로 함수 3번 연속 콜함
#!/bin/bash
clear
pwd
echo $0
echo "----------------------------"
testFn(){
echo "testFn()..."
echo $1 $2 $3
echo $(($1+$2+$3))
echo total=$(($1+$2+$3))
}
testFn 11 22 33
echo $(testFn 11 22 33)
#not defined position parameter($1, $2, $3)
#total=$$(($1+$2+$3))
echo "----------------------------"
sum(){
fsum=0
for item in $@
do
fsum=$((fsum+item))
done
echo sum=$fsum
}
sum 1 2 3 4 5 6 7 8
echo $(sum 1 2 3 4 5 6 7 8)
for i in $(seq 3)
do
sum 11 22 33
done
exit 0
-------------------------------------------
** 개발할 땐, 더미값으로 먼저 오류를 확인하고, read 같은 인풋 명령은 항상 마지막에 넣는다.
# mission 1 : 성적처리 함수를 콜하면 3명의 성적을 받아서 출력하도록 만들어라.
(단, 함수 안에는 총점 평균 등급만 처리하고, 따로 루프를 돌려서 점수 받는 것과 함수 콜만 실행할 것)
<순서> //for가 3번 돌아가는지 확인 >> 더미값으로 넣고 $1,2,3,4로 실행 >> read문 추가
#!/bin/bash
clear
pwd
echo $0
echo "----------------------"
#name kor eng math total avg grade
score(){
#echo "score()..."
#echo $1 $2 $3 $4
total=$(($2+$3+$4))
avg=$((total/3))
grade="A"
if ((avg>=90));then
grade="A"
elif ((avg>=80));then
grade="B"
elif ((avg>=70));then
grade="C"
elif ((avg>=60));then
grade="D"
else
grade="F"
fi
printf "name[%s]: kor[%d],eng[%d],math[%d],total[%d],avg[%.2f],grade[%s]\n" $1 $2 $3 $4 $total $avg $grade
}
for i in $(seq 3)
do
read -p "input name:" name
read -p "input kor:" kor
read -p "input eng:" eng
read -p "input math:" math
echo $(score $name $kor $eng $math)
done
exit 0
# mission 2 : 성적처리 함수를 콜하면 3명의 성적을 받아서 출력하도록 만들어라. (값을 배열로 받아볼 것)
// list 생성 - 시퀀스 0~2 - 리스트[인덱스] 값넣기 - 출력문 배열
// 값 넣는게 바로 이어지는 차이가 있다.
// printf로 리턴값을 만들 때는 장식적인 문자열이 들어가지 않도록 주의 필요
#!/bin/bash
clear
pwd
echo $0
echo "----------------------------"
#name kor eng math total avg grade
score(){
total=$(($2+$3+$4))
avg=$((total/3))
grade="A"
if((avg>=90));then
grade="A"
elif((avg>=80));then
grade="B"
elif((avg>=70));then
grade="c"
elif((avg>=60));then
grade="D"
else
grade="F"
fi
printf "%s %d %d %d %d %.2f %s" $1 $2 $3 $4 $total $avg $grade
}
list=()
for i in $(seq 0 2);
do
read -p "input name:" name
read -p "input kor:" kor
read -p "input eng:" eng
read -p "input math:" math
#name="kim"
#kor=11
#eng=22
#math=33
list[i]=$(score $name $kor $eng $math)
done
echo ${list[@]}
echo "---------------------------------"
for item in "${list[@]}"
do
echo $item
done
exit 0
#jq - json을 파싱하는 패키지(라이브러리)
//jq패키지를 추가로 설치해야 사용가능하다.
- $sudo apt install -y jq
//JSON 형식으로 쓰여진 텍스트를 파싱할 때 사용한다.
- [] - 배열 (인덱스-값) , {} - 객체 (키-값)
- 나중에 레스트 컨트롤러에서 읽어온 값이 제이슨일 때 활용할 수 있다.
- Java의 Jackson 형식, JS의 object 형식과 같음
//Jq를 사용하는 2 가지 방법
** 웹페이지를 cat으로 읽어오게되고, cat외에도 head /tail등 다양한 변화가 가능해서 1번이 더 자주 사용됨.
- cat으로 읽어들인 텍스트를 jq로 처리하는 방법(뒷 내용 참조) : cat sh17temp2.json |jq '.[0].id'
- jq 단독으로 읽어오는 방법 : jq ".vo.id" sh17temp.json
//넘어온 데이터를 읽어내는 역할로 $cat 외에 $head / $tail 도 함께 활용할 수 있다.
- head 앞줄 읽기 / tail 뒷줄 읽기 (-숫자 : 읽는 줄 수 지정 옵션)
- 넘어온 데이터에 특정 위치의 줄이 제이슨일 때 같이 활용한다.
// . 은 ~안에 라는 뜻임을 기억하자.
//데이터 안의 특정 인덱스나 키 값을 활용하여 특정 값만 읽어올 수 있다.
- jq "." 파일명 : 파일 안 모든 값을 불러와줘
- jq ".vo" 파일명 : "vo"에 있는 내용을 불러와줘
- jq ".vo.id" 파일명 : "vo"가 가진 값 중 "id"값을 불러와줘
- jq ".arr" 파일명 : "arr"에 있는 내용을 불러와줘
- jq ".arr[1]" 파일명 : "arr" 배열 값 안에 1번 인덱스 값을 불러와줘
<jq 단독으로 읽어오는 방법>
#!/bin/bash
clear
pwd
echo $0
echo "----------------------------"
cat > sh17temp.json << END
{
"name":"kim",
"vo":{"id":"admin"},
"arr":[11,22,33]
}
END
echo "----------------------------"
cat sh17temp.json
echo "----------------------------"
#sudo apt install -y jq
echo "----------------------------"
jq "." sh17temp.json
echo "----------------------------"
jq ".vo" sh17temp.json
echo "----------------------------"
jq ".arr" sh17temp.json
echo "----------------------------"
jq ".vo.id" sh17temp.json
echo "----------------------------"
jq ".arr[0]" sh17temp.json
jq ".arr[1]" sh17temp.json
jq ".arr[2]" sh17temp.json
exit 0
<cat으로 읽어들인 텍스트를 jq로 처리하는 방법>
echo "----------------------------"
cat > sh17temp2.json << END
[
{"id":"admin1","pw":"hi1234561"},
{"id":"admin2","pw":"hi1234562"},
{"id":"admin3","pw":"hi1234563"}
]
END
cat sh17temp2.json
echo "----------------------------"
cat sh17temp2.json |jq '.'
echo "----------------------------"
cat sh17temp2.json |jq '.[0]'
echo "----------------------------"
cat sh17temp2.json |jq '.[0].id'
cat sh17temp2.json |jq '.[0].pw'
echo "----------------------------"
//curl과 jq를 혼합하여 웹상의 데이터를 읽어올 수 있다.
- $curl (-s옵션) 데이터 읽어올 때 통신 정보는 출력 안함
- $jq (-r옵션) 최종 값에 " "표시를 없애줘 (ex. "admin" >> admin)
* -r은 배열 데이터의 최종 키값으로 대응되는 최하위단의 데이터를 단독 출력할 때만 적용됨.