jq는 JSON과 같은 데이터 타입을 지원한다는 점을 기억해 두어요.
JSON은 문자열을 이렇게 설명해요:
문자열은 0개 이상의 유니코드 문자 시퀀스이며, 큰따옴표로 감싸고 백슬래시 이스케이프를 사용해 표현해요.
문자열 안에서는 백슬래시 문자를 사용해 "특수한" 문자를 넣어요:
\": 문자 그대로의 큰따옴표\\: 문자 그대로의 백슬래시\n, \t, \r, \f, \b
\uAAAA (A는 16진수 숫자)문자의 개수를 구하려면 length 함수를 사용해요.
$ jq -cn --args '$ARGS.positional[] | length' "Hello world!" "❄🌡🤧🤒🏥🕰😀"
12
7
실제 바이트 수를 구하려면 utf8bytelength 함수를 사용해요.
$ jq -cn --args '$ARGS.positional[] | utf8bytelength' "Hello world!" "❄🌡🤧🤒🏥🕰😀"
12
27
슬라이스 표기법을 사용하면 부분 문자열을 추출할 수 있어요.
문법은 .[i:j]예요.
반환되는 부분 문자열의 길이는 j - i이고, 인덱스 i(포함)부터 인덱스 j(미포함)까지의 문자를 반환해요.
각 인덱스는 음수가 될 수 있는데, 그러면 문자열의 끝에서부터 거꾸로 세요.
각 인덱스는 생략할 수도 있고, 그러면 문자열의 시작이나 끝을 가리켜요.
인덱스는 0부터 시작해요.
"abcdefghij"[3:6] # => "def"
"abcdefghij"[3:] # => "defghij"
"abcdefghij"[:-2] # => "abcdefgh"
문자열을 이어 붙이려면 +를 사용해요:
"Hello" + " " + "world!"
# => "Hello world!"
문자열 배열이 주어졌을 때는 add를 사용해요:
["Hello", " ", "world!"] | add
# => "Hello world!"
문자열을 나눌 때는 split/1 함수나 / 연산자를 사용해요:
"Hello beautiful world!" | split(" ") # => ["Hello", "beautiful", "world!"]
"Hello beautiful world!" / " " # => ["Hello", "beautiful", "world!"]
문자열을 문자 배열로 바꾸는 일은 자주 필요해요. 이를 위한 방법이 두 가지 있어요:
빈 문자열을 기준으로 나누기
"Hi friend 😀" / "" # => ["H","i"," ","f","r","i","e","n","d"," ","😀"]
explode로 코드포인트 배열 만들기
"Hi friend 😀" | explode # => [72,105,32,102,114,105,101,110,100,32,128512]
index/1 함수를 사용해요. 인덱스는 0부터 시작해요.
"hello" | index("el")' # => 1
문자열에 부분 문자열이 없으면 결과는 null이에요.
"hello" | index("elk") # => null
그 밖에 유용한 함수로는 rindex/1과 indices가 있어요.
문자열 안에서 \(expression) 시퀀스는 그 표현식의 _결과_를 문자열에 넣어요:
"The current datetime is \(now | strflocaltime("%c"))" # => "The current datetime is Wed Nov 16 17:06:33 2022"
ascii_downcase와 ascii_upcase 함수를 사용해 문자열의 대소문자를 바꿔요.
tonumber 함수를 사용해 문자열에서 숫자를 만들어요.
문자열을 숫자로 변환할 수 없으면 오류가 발생하므로 try-catch가 필요할 수 있어요.
$ jq -cn --args '$ARGS.positional[] | [., tonumber]' 42 3.14 oops 1e6 0xbeef
["42",42]
["3.14",3.14]
jq: error (at <unknown>): Invalid numeric literal at EOF at line 1, column 4 (while parsing 'oops')
$ echo $?
5
$ jq -cn --args '$ARGS.positional[] | try [., tonumber] catch "not a number"' 42 3.14 oops 1e6 0xbeef
["42",42]
["3.14",3.14]
"not a number"
["1e6",1000000]
"not a number"
JSON 숫자에는 일부 언어가 지원하는 16진수나 8진수 형태가 없다는 점에 주의해요.
이 함수들에 대한 자세한 내용은 매뉴얼을 확인해요:
*
contains/1, inside/1, indices/1, index/1, rindex/1, startswith/1, endswith/1
lsrimstr/1, rtrimstr/1
@text, @json, @html, @uri, @csv, @tsv, @sh, @base64, @base64d
jq는 정규 표현식을 풍부하게 지원해요. 이 주제는 나중 강의에서 다뤄요.