처음으로 지인의 부탁을 받아 shell 스크립트를 짜 보았습니다.

csh로 짰는데, 생각보다 자료가 적어서 크게 당황하였고, 대부분의 자료는 영어였으며, 프로그래밍의 다양성을 존중하는 언어인지 같은 상황에 대해 10가지 문서에서 10가지 다른 프로그래밍 방식을 사용하더군요.

그리고 기본적인 내용을 한번 정리해 보기로 하였습니다.

전에도 한번 했었는데, 워낙 생소한 분야라 한번 익숙해졌다가도 다시 초기화되어 저도 기록을 남깁니다.

작성해본 스크립트는 씨 쉘(csh) 기준입니다.

  • csh, bash 차이에 따라서 프로그래밍 언어도 차이가 있는 것 같습니다.

0) 셸 스크립트 작성 및 실행법

파일 최상단에

#!/bin/csh
#
# comment

입력 후 하단에 쉘 스크립트를 작성해주시면 됩니다.
파일명의 확장자는 .csh이며, mac에서 사용시 그냥 터미널에서 csh 명령어 이후에 파일이름을 써주시면 스크립트 파일이 실행됩니다.
여기서 최상단 문장을 제외한 #으로 시작하는 문장은 전부 주석입니다.

1) 기본적인 변수선언 및 변수 사용

set var = "Hello"

echo $var

2) 쉘스크립트 실행 후 결과값을 변수에 저장

set ls = `ls`

echo $ls

여기서 ` 부분은 작은 따옴표가 아니라 그레이브 혹은 백틱 이라는 탭 키 위에 있는 문자입니다.
이 그레이브로 쌓인 문장은 쉘에서 실행된 뒤 그 결과를 반환하는 약간의 '부분실행' 명령어 같은 것입니다.
여기서는 배쉬(bash) 명령어인 ls로 현재 디렉토리의 파일 리스트를 읽어온 뒤 그것을 다시 ls라는 변수에 저장하였습니다.

3) 파이프 명령어(pipe operation, |)

|는 엔터 근처에 있는 \표시 혹은 백슬래시기호를 시프트 키를 누른 채 누르면 써지는 파이프 기호입니다.
csh에서 이 파이프 기호는 왼쪽 명령의 결과를 오른쪽 명령의 인풋으로 사용한다는 뜻입니다.

4) 파일 출력 명령어 >

> 는 파일을 출력하라는 명령어이며, 왼쪽의 결과를 오른쪽에 쓰는 파일 이름으로 저장합니다,
예를 들어
echo "Hi" > hi.txt
라고하면 hi.txt라는 파일에 Hi가 입력된 채로 파일이 생성됩니다.

5) foreach

사실 요새는 for 보다는 foreach 같이 내부 요소를 순환하는 명령이 사용하기 더 편합니다. (직접적으로 수의 증감이 필요한 경우 제외하고)
csh에서 foreach명령문의 형태는 아래와 같습니다.

foreach var1 ( $var2 )

    echo $var1

end

즉, var2에 저장된 요소들을 하나씩 var1에 저장하며 for문을 도는 것입니다.
여기서는 단순히 출력만을 합니다.
조금 더 활용하면

foreach var1 ( `명령` )

    echo $var1

end

와 같이 활용할 수도 있습니다. 직접적으로 명령을 입력해서 그 출력을 foreach의 순회 요소로 만드는 것이지요.

6) if

if (조건문) then

    실행문

endif

if는 위와 같은 구조로 구성됩니다.
여기서 조건문의 or와 and는 c와 같은 ||, && 연산자로 처리할 수 있습니다.
또한 같다 다르다의 명령 또한 c와 같은 ==, !=입니다.
추가적으로 텍스트 비교를 위해서는 단순히 $text1 == $text2라고 하면 "if: Expression syntax"에러를 내기 때문에 `echo $text1 ` == `echo $text2`의 변형기출이 필요합니다.

7) 파일 경로 조작

전체 파일 경로에서, 끝에 :t를 붙이면 확장자를 포함한 파일 명만 나오고, :r을 추가로 붙이면 확장자를 제외한 파일 명을 리턴해줍니다.
즉, "/dir1/test.txt":t:r을 써주시면 test만 출력됩니다.
더욱 자세한 정보는 이곳을 클릭해주세요.

8) awk

사실 awk만으로도 단순 쉘 스크립트 뿐만이 아닌 거의 독자적인 문서 리딩 명령이라고 할 수 있습니다.
그래서 awk를 사용하기 위해서도 복잡한데 기본적인 것들만 정리해보도록 하겠습니다.
기본적으로 awk는 문서를 순차적으로 한줄씩 읽어내려간다고 생각하시면 됩니다.
awk의 기본 형태는
awk '조건 및 실행문' 입력파일
입니다.
입력파일
이 부분에서 파일 입력을 받아서 조건 및 실행문에서 조건에 맞게 무언가를 실행하고 그것을 출력하는 함수입니다.
여기서 cat 입력파일 | awk '조건 및 실행문'으로 입력해도 됩니다. (cat은 단순히 입력파일의 내용을 보여주는 함수입니다.)
'조건 및 실행문'
이 안에서 awk에서 제공하는 조건문은 그냥 작성 됩니다. (같다/다르다 ==/!= 명령, or/and명령 ||/&& 사용가능)
그리고 built-in variables라고, 내장 변수와 함수들이 존재합니다.
$0 : 전체 라인
$1 : 첫번째 열
$2 .. $n : n번째 열
NR : 행 번호(가령 첫번째 행은 1)
length(변수) : 변수의 길이
이외에도 더 있지만, 가장 자주 쓰는 내장 변수들은 이정도입니다. 더 궁금하시면 구글링 해보시면 됩니다.
또한 정규표현식(regex)도 사용할 수 있습니다.
/정규표현식/로 사용이 가능하며, 시작 끝표현인 ^ $ 등 정규표현식에서 사용하는 방식은 전부 사용됩니다.
기본적으로 아무것도 써주지 않고 조건만 써주면 현재 라인 전체에서 찾습니다.
정규표현식에서 built-in variables를 사용하기 위해선 ~ 명령어로 '이 안에서 찾아라'라는 것을 명시해 주어야 합니다.
가령
/hello/, $0 == "hello", $0~/hello/
위의 세 명령어는 전부 같은 조건입니다.
NR==1, NR==5를 조건으로 입력하면 첫번째 행부터 5번째 행까지 출력합니다.
단순히 NR<6으로 작성할 수도 있습니다.
기본적으로 awk에서 조건에 맞는 결과는 바로 리턴해줍니다. 그러나 awk내에서 csh과 같은 프로그래밍 문법을 사용하려면 대괄호(brace, {})안에 작성하여야 합니다.
기본적으로 if (), print, printf, substr(), length(), for(;;)등 사용 가능합니다.
예시로
awk '$1=="test" {printf "%s %s",$3,substr($4,1,length($4)-1)}' test.txt
같이 사용하며
print안에서 연속해서 변수를 출력할경우 print $1,$2와 같이 콤마로 연결하여 쓰며, 여러 명령어를 동시에 사용할 땐 print $1 print $2와 같이 공백으로 연결해줍니다. 혹은 명시적으로 세미콜론으로 구분지어주기도 합니다.
print명령의 경우 뒤에 아무 것도 쓰지 않으면 전체 줄 출력, print $1과 같이 변수 입력하면 해당 변수 출력합니다.

8-1) awk 심화(문서 조건)

awk의 조건명령문 안에서 대괄호는 세미콜론으로 연결됩니다.
또한 BEGIN, END등의 명령으로 문서의 시작점과 끝점에서 특정하게 실행시킬 명령문을 지정할 수 있습니다.
awk 'BEGIN {print};END {print}' test.txt 명령은 처음 한줄과 끝 한줄만을 출력합니다.

8-2) awk 심화(변수 passing)

awk를 사용하다보면, csh의 변수를 awk에서 사용해야 할 때도 있고, 반대로 awk의 결과를 변수로 저장해야 할 경우도 있습니다.
사실 이 경우가 정말 검색에서 잘 안나오는데, 하나하나 설명드리겠습니다.

1) csh변수 -> awk변수

-v

가장 흔히 쓰는 방식은 -v 명령을 통하여 변수를 링크시키는 것입니다.
예를 들면 awk -v var=$ex_var 'print var'라는 명령에서 csh의 ex_var라는 변수를 awk 내부의 var라는 변수로 대입시켜 print하는 명령입니다.

'"${}"'

awk내에서 '"${변수이름}"'식으로 shell variable을 awk내에서 사용 가능합니다.
2) awk변수 -> csh변수
이게 진짜 아무데도 안나오고, csh에 맞게 설명되어있는 부분이 없습니다.
인터넷에 declare, source, eval 이런 명령어들을 사용하는데, 정말 단순합니다.

set var = `awk '{print}' test.txt`

echo $var
var = $(awk 'NR>5 {print}' test.txt)

echo $var

이렇게 하면, test.txt에 쓰여져 있는 것들이 print로 출력되며, 이 결과가 var라는 csh변수에 저장되고, 이것을 echo가 출력하게 됩니다.

9) 기타 shell script 명령어들

1) for

for i in {start..end...step}
do
    내용
done

2) foreach

foreach i ( 1 2 3 4 5 )
    내용
end

3) if

if (condition) then
endif
if [condition] then
elif [condition] then
else
fi

만약 더 사용하게되며 추가적으로 알게되는 내용은 실시간으로 업데이트 예정입니다.

'Software > Shell script' 카테고리의 다른 글

[csh] data extractor  (0) 2020.01.19
#!/bin/csh
#
# data extractor
#

set lat = "60 22.77700N"
set lon = "42 54.63700W"

foreach file ( `ls` )
   echo $file
   set clat = `awk '$1=="Latitude" {printf "%s %s",$3,substr($4,1,length($4)-1)}' $file`
   set clon = `awk '$1=="Longitude" {printf "%s %s",$3,substr($4,1,length($4)-1)}' $file`
   # set clat = `cat $file | awk '$1=="Latitude" {printf "%s %s",$3,substr($4,1,length($4)-1)}'`
   # set clon = `cat $file | awk '$1=="Longitude" {printf "%s %s",$3,substr($4,1,length($4)-1)}'`
   if (`echo $lat` == `echo $clat` && `echo $lon` == `echo $clon`) then
      set sl = `cat $file | awk '{if (NR>40 && $1=="//") print NR}'`
      # set sl = `cat $file | awk '{if (NR>40 && $1~/\/\//) print NR}'`
      awk -v sl=$sl 'NR>sl {print}' $file > $file:t:r_ext.txt
      # cat $file | awk -v sl=$sl 'NR>sl {print}' > $file:t:r_ext.txt
   endif
end

'Software > Shell script' 카테고리의 다른 글

[Linux/shell/bash/csh] shell 스크립트 튜토리얼  (0) 2020.01.20

+ Recent posts