Bash awk관련 내용 메모

입질쾌감 물때표

# grep 문 사용하기

cat KR-160315.csv | awk -F"," 'NR > 1 {printf "%-5s|%-10s|%-30s\t|%-5s|%-15s|%-5s|%s\n", $1,$2,$4,$5,$6,$8,$10 | "grep 00K1" }' | head
cat KR-160315.csv | awk -F"," 'NR > 1 {printf "%-5s|%-10s|%-40s|%-5s|%-15s|%-5s|%-s\n", $1,$2,$4,$5,$6,$8,$10}' | head

 

&를 쓰면 매칭된 스트링이 대치된다.

user1@ubuntu-desktop:~/Downloads$ echo "candidate a b c " | awk '{ sub(/candidate/, "& and his wife"); print }'
candidate and his wife a b c

 

# sub와 gsub의 차이는 모두 바꾸는지 여부다

user1@ubuntu-desktop:~/Downloads$ awk 'BEGIN { str = "da33*32/baaa"; sub(/[0-9]+/, "c", str); print str}'
dac*32/baaa
user1@ubuntu-desktop:~/Downloads$ awk 'BEGIN { str = "da33*32/baaa"; gsub(/[0-9]+/, "c", str); print str}'
dac*c/baaa

 

# match 사용방법

user1@ubuntu-desktop:~/Downloads$ awk 'BEGIN { print match("abbcd", /c/)}'
4

 

# 10데니어 이하로 검색

cat KR-160315.csv | gawk -F”,” ‘NR > 1 { rtn=gensub(/[.\(]*([0-9]*)[\/\*\+]+.*/, “\\1”, “g”, $4); if(int(rtn)<10) { printf “%-5s|%-10s|%-40s|%-5s|%-15s|%-5s|%-s\n”, $1,$2,$4,$5,$6,$8,$10 } }’

# 10~20데니어 중간으로 검색
user1@user1-1215N:~/Downloads$ cat KR-160315.csv | gawk -F”,” ‘NR > 1 { rtn=gensub(/[.\(]*([0-9]*)[\/\*\+]+.*/, “\\1”, “g”, $4); if(int(rtn)<20 && int(rtn)>10) { printf “%-5s|%-10s|%-40s|%-5s|%-15s|%-5s|%-s\n”, $1,$2,$4,$5,$6,$8,$10 } }’

# PA6이지만 PA66은 아닌것을 검색
user1@user1-1215N:~/Downloads$ cat KR-160315.csv | gawk -F”,” ‘/PA6/ && !/PA66/ NR > 1 { rtn=gensub(/[.\(]*([0-9]*)[\/\*\+]+.*/, “\\1”, “g”, $4); if(int(rtn)<20 && int(rtn)>10) { printf “%-5s|%-10s|%-40s|%-5s|%-15s|%-5s|%-s\n”, $1,$2,$4,$5,$6,$8,$10 } }’

cat KR-160315.csv | gawk -F”,” ‘/PA6/ && !/PA66/ && NR > 1 { rtn=gensub(/[.\(]*([0-9]*)[\/\*\+]+.*/, “\\1”, “g”, $4); if(int(rtn)<20 && int(rtn)>10) { printf “%-5s|%-10s|%-40s|%-5s|%-15s|%-5s|%-s\n”, $1,$2,$4,$5,$6,$8,$10 } }’

# trim 시키는 방법

cat KR-160315.csv | gawk -F"," '/RIPSTOP/ && NR > 1 { gsub(/[ \t]+$/, "", $1); printf "%-6s|%-10s|%-40s|%-5s|%-15s|%-5s|%-s\n", $1,$2,$4,$5,$6,$8,$10 }'
cat KR-160315.csv | gawk -F"," '/RIPSTOP/ && NR > 1 { gsub(/[ \t]+$/, "", $1); gsub(/[ \t]+$/, "", $2); printf "%-6s|%-10s|%-40s|%-5s|%-15s|%-5s|%-s\n", $1,$2,$4,$5,$6,$8,$10 }'
cat KR-160315.csv | gawk -F"|" '/RIPSTOP/ && NR > 1 { gsub(/[ \t]+$/, "", $3); gsub(/[ \t]+$/, "", $4); printf "%-6s|%-10s|%-30s|%-25s|%-5s|%-15s|%-5s|%-5s|%s\n", $3,$4,$6,$13,$7,$8,$9,$10,$12 }'

 

# 5번셀이 N인 것과 16셀이 Y인것만 검색해서 출력

cat PRICE.csv | gawk -F"|" 'NR > 1 && $5!="N" && $16=="Y" { gsub(/[ \t]+$/, "", $1); gsub(/[ \t]+$/, "", $2); printf "%-6s|%-10s|%-5s|%-5s|%-5s\n", $1,$2,$17,$3,$18 }'

 

# 1번셀 2번셀 사이에 “-” 넣기

cat PRICE.csv | gawk -F"|" 'NR > 1 && $5!="N" && $16=="Y" { gsub(/[ \t]+$/, "", $1); gsub(/[ \t]+$/, "", $2); key=$1"-"$2; printf "%15s|%-6s|%-10s|%-5s|%-5s|%-5s\n", key,$1,$2,$17,$3,$18 }'

cat PRICE.csv | gawk -F"|" 'NR > 1 && $5!="N" && $16=="Y" { gsub(/[ \t]+$/, "", $1); gsub(/[ \t]+$/, "", $2); key=$1"-"$2; printf "%15s|%s\n", key,$4 }'

 

sort 사용방법

sort -t"|" -k 3
; -t : 구분자, -k 필드번호

 

# 쉘에서 변수로 넘기는 방법 -v 옵션을 사용해서 넘기면 되는데, 변수별로 각각 옵션을 줘야 한다.

T_LIMIT=50
B_LIMIT=30

cat KR-160315.csv | gawk -v “t_limit=$T_LIMIT” -v “b_limit=$B_LIMIT” -F”|” ‘BEGIN { OFS=”|” } NR > 1 { gsub(/[ \t]+$/, “”, $3); gsub(/[ \t]+$/, “”, $4); key=$3″-“$4; rtn=gensub(/[.\(]*([0-9]*)[\/\*\+]+.*/, “\\1”, “g”, $6); if(int(rtn)<t_limit && int(rtn)>b_limit) { print key, $3,$4,$6,$13,$7,$8,$9,$10,$12 } }’

################################################################################
#!/bin/bash

#T_LIMIT=50
#B_LIMIT=30

T_LIMIT=2000
B_LIMIT=1

PRICE=4

GREP=”-v \(WR\|Soft\)”
GREP=”\*”
GREP=”\(DOBBY\|PLAIN\)”

# 기준데이터 테스트
cat KR-160315.csv | gawk -v “t_limit=$T_LIMIT” -v “b_limit=$B_LIMIT” -F”|” ‘BEGIN { OFS=”|” } NR > 1 { gsub(/[ \t]+$/, “”, $3); gsub(/[ \t]+$/, “”, $4); key=$3″-“$4; rtn=gensub(/[.\(]*([0-9]*)[\/\*\+]+.*/, “\\1”, “g”, $6); if(int(rtn)<t_limit && int(rtn)>b_limit) { print key, $3,$4,$6,$13,$7,$8,$9,$10,$12 } }’ | sort -t”,” -k 1 >/tmp/fabric_fd

# 가격데이터 테스트

cat PRICE.csv | gawk -F"|" 'BEGIN { OFS="|" } NR > 1 && $5!="N" && $16=="Y" { gsub(/[ \t]+$/, "", $1); gsub(/[ \t]+$/, "", $2); key=$1"-"$2; print key,$1,$2,$17,$3,$18,$4 }' | sort -t"|" -k 1 >/tmp/price_fd

join -t"|" -a 1 -1 1 -2 1 -o 0,1.4,1.5,1.6,1.7,1.8,1.9,1.10,2.4,2.5,2.6,2.7 \
<(cat </tmp/fabric_fd) \
<(cat </tmp/price_fd) | \
gawk -v "limit_price=$PRICE" -F"|" \
'BEGIN { printf "%15s|%-35s|%-22s|%-5s|%-15s|%-5s|%-10s|%-10s|%-90s|%-10s|%-15s\n", "ITEM_CODE","SPEC","COMPOSITION","WIDTH","STRUCTURE","WT_Y","WT_M","PRICE","REMARK","AD","COLOR" } \
{ if($9<limit_price && $9!="") printf "%15s|%-35s|%-22s|%-5s|%-15s|%-5s|%-10s|%-10s|%-90s|%-10s|%-15s\n", $1,$2,$3,$4,$5,$6,$7,$9,$8,$10,$12 }' >/tmp/result_fd

if [[ -n "$GREP" ]]; then
    cat /tmp/result_fd | (head -n 1; grep $GREP)
else
    cat /tmp/result_fd
fi

# 반올림 하는 방법

price = sprintf("%.2f",price/0.9144/exrate/0.9); \

 

# 문자 &를 교체할때에는 백슬래쉬 반드시 넣을 것

echo "abcd45*333alkk" | gawk '{ sub(/333/, "\\&", $0); print $0; }'

 

# gsub와 sub의 차이는 전체 치환인지 한개 치환인지를 구분한다.

$ echo "abcd45*333alkk" | gawk '{ sub(/[0-9]/, "#", $0); print $0; }'
abcd#5*333alkk
$ echo "abcd45*333alkk" | gawk '{ gsub(/[0-9]/, "#", $0); print $0; }'
abcd##*###alkk

 

# [0-9]*의 의미는 숫자가 0개이상 일치하는지를 테스트를 한다. 따라서 숫자가 없어도 모든 문자와 매칭이 되므로 아래와 같은 현상이 일어난다.

$ echo "abcd45*333alkk" | gawk '{ gsub(/[0-9]*/, "#", $0); print $0; }'
#a#b#c#d#*#a#l#k#k#

 

# 아래의 의미는 전체 텍스트에서 “333” 문자열을 찾아서 \\1로 치환하고 그 결과를 출력하라는 것.
그러나 \\1의 값은 없기 때문에 333을 제외한 문자가 출력되게 된다.

$ echo "abcd45*333alkk" | gawk '{ print(gensub(/333/, "\\1", "g", $0)) }'
abcd45*alkk

 

# 따라서 아래의 형식은 잘못된 표현이다. “45”숫자와 일치했지만, 교체하는 문자가 “45”이므로 결과는 동일하다.

$ echo "abcd45*333alkk" | gawk '{ print(gensub(/([0-9]+)/, "\\1", "g", $0)) }'

$ echo "abcd45*333alkk" | gawk '{ print(gensub(/([0-9]+)9([0-9]+)/, "\\1------\\2", "g", $0)) }'
abcd45*333alkk
$ echo "abcd45*333alkk" | gawk '{ print(gensub(/([0-9]+)\*([0-9]+)/, "\\1------\\2", "g", $0)) }'
abcd45------333alkk

 

# 매칭된 문자열만 따로 출력하는 방법

$ echo "83+28/838*383" | gawk '{ match($0, /[0-9]+\*[0-9]+/); print substr($0,RSTART,RLENGTH); }'
838*383

 

# 다른 방법 소개 () 감싼 match 함수는 순서대로 rtn 변수에 배열로 담아준다.

$ echo "83+28/838*383" | gawk '{ match($0, /([0-9]+\*[0-9]+)/, rtn); print rtn[1]; }'
838*383

 

# {} brace 뒤에 예를 들어 1로 작성했을 경우, { }값의 결과는 수학적인 평가로 항상 TRUE를 반환하게 된다는 의미이다.

awk '{$0=int($0)}1' <<< "26.3"

 

 

awk 사용방법

user1@user1-laptop:~$ awk "NR==$line{print}" /etc/resolv.conf
user1@user1-laptop:~$ awk 'BEGIN {print "%.3f\n", 2005.50/3}'

 

파일 목록을 탭 구분으로 화면에 출력하기

ls -ail | awk -v OFS="\t" '$1=$1'

 

FILENAME 현재 처리하고 있는 file의 이름
FS Field Separator- 필드 구분자
RS Record Separator – 레코드 구분자
NF Number of Fields – 현재 레코드의 필드 수
NR Number of Records – 현재 레코드의 번호
$1 입력되는 Record의 첫 번째 필드
$n 입력되는 Record의 n 번째 필드
OFS Output Fields Separator – 출력시의 FS.
이 값을 변경하게 되면, 출력시의 FS가 바뀌게 됩니다.
ORS Output Records Separator – 출력시의 RS.
이 값을 변경하게 되면, 출력시의 RS가 바뀌게 됩니다

Eric suggests to better use the “tr” utility to convert CRLFs to LFs on Windows:
tr -d \r

21. Convert Windows/DOS newlines (CRLF) to Unix newlines (LF) from Unix.

awk ‘{ sub(/\r$/,””); print }’
This one-liner uses the sub(regex, repl, [string]) function. This function substitutes the first instance of regular expression “regex” in string “string” with the string “repl”. If “string” is omitted, variable $0 is used. Variable $0, as I explained in the first part of the article, contains the entire line.

The one-liner replaces ‘\r’ (CR) character at the end of the line with nothing, i.e., erases CR at the end. Print statement prints out the line and appends ORS variable, which is ‘\n’ by default. Thus, a line ending with CRLF has been converted to a line ending with LF.

22. Convert Unix newlines (LF) to Windows/DOS newlines (CRLF) from Unix.

awk ‘{ sub(/$/,”\r”); print }’
This one-liner also uses the sub() function. This time it replaces the zero-width anchor ‘$’ at the end of the line with a ‘\r’ (CR char). This substitution actually adds a CR character to the end of the line. After doing that Awk prints out the line and appends the ORS, making the line terminate with CRLF.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다