2020년 9월 16일 수요일

[리눅스와 bash] 파일 목록의 배열 만들기

현재 디렉토리에 a1, a2, a3...a10이라는 파일이 있다고 가정하자. 파일 이름을 배열로 전환하여 각각에 대해 원하는 작업을 하고 싶다면? 구글을 뒤져서 방법을 찾아 보았다. 여기에 소개는 하지만 완벽하게 그 원리를 이해한 것은 아니다. 'VAR=$(command)'에 익숙해진 것도 비교적 최근의 일이다. 예전에는 오로지 backtick 또는 backquote라 불리는 특수문자(`)를 이용하여 명령어를 둘러싸는 이른바 command substitution만 사용했었으니까.

내가 바이블처럼 참조하는 Mark G. Sobel의 A Practical Guide to the UNIX System 제3판(1995년 9월 26일 구입)에도 shell에서 파일 목록을 배열로 전환하여 다루는 방법은 나오지 않는다. 다음의 자료를 참고하면 bash에서 배열을 다루는데 익숙해 지리라 믿는다.

The Ultimate Bash Array Tutorial with 15 Examples

[Linux Documentation Project - Advance Bash-Scripting Guide] Chapter 27. Arrays

$ ls a*
a01  a02  a03  a04  a05  a06  a07  a08  a09  a10
$ var=$(ls a*)
$ echo $var
a01 a02 a03 a04 a05 a06 a07 a08 a09 a10
$ arr=(a*) # 괄호로 둘러싸야 배열 형태로 반환된다.
# 'arr=($(ls a*))'라고 하면 넌센스일까?
$ echo $arr # 왜 이것이 'echo ${arr[0]}와 결과가 같은지 잘 모르겠다.
a01
$ echo ${arr[1]} # 인덱스는 0부터 시작한다.
a02
$ echo ${#arr[@]} # 배열의 크기
10
$ i=4
$ echo ${arr[4]}
a05
$ echo ${arr[$i]}
a05
$ echo ${arr[i]}
a05

# 각 원소에 대하여 반복하기
$ for f in "${arr[@]}"
> do
> echo "$f"
> done
a01
a02
a03
a04
a05
a06
a07
a08
a09
a10

# 인덱스를 변수로 뽑아서 반복해 보자. 좀 더 난해하다.
$ for i in ${!arr[*]}
> do
> echo $i ${arr[i]}
> done
0 a01
1 a02
2 a03
3 a04
4 a05
5 a06
6 a07
7 a08
8 a09
9 a10

# 다음 명령을 이해할 수 있는가?
$ echo ${!arr[*]}
0 1 2 3 4 5 6 7 8 9
$ echo ${arr[*]}
a01 a02 a03 a04 a05 a06 a07 a08 a09 a10
$ echo ${arr[@]} # '*' 대신 '@'를 넣어도 작동한다.
a01 a02 a03 a04 a05 a06 a07 a08 a09 a10

Bash에서 구사할 수 있는 스크립트 작성 테크닉의 5% 정도는 활용하고 있는 것일까?

댓글 없음: