7  파일, 텍스트, 폴더 찾기

리눅스가 유닉스의 유산을 이어받은 것은 분명하지만, 코드까지 물려받은 것은 아니다. 우리는 그런 주장을 한 적도 없고 할 생각도 없다. Obviously Linux owes its heritage to UNIX, but not its code. We would not, nor will not, make such a claim.

많은 사람들이 “구글(Google)”을 “검색”을 의미하는 동사로 사용하는 것처럼, 유닉스 프로그래머들은 “grep”을 같은 방식으로 사용한다. grep은 “global/regular expression/print(전역/정규표현식/출력)”의 축약어로, 초기 유닉스 편집기에서 흔히 사용되던 연산작업 시퀀스를 가리킨다. 이는 매우 강력하고 유용한 명령라인 프로그램의 이름이기도 하다.

7.1 grep 명령어

grep은 패턴과 일치하는 파일의 행을 찾아서 출력해주는 도구다.

“grep”은 “global regular expression print”의 줄임말로, 유닉스 시스템에서 가장 자주 사용되는 텍스트 검색 도구 중 하나다. 시스템 로그 분석부터 소스 코드 검색, 데이터 마이닝까지 다양한 용도로 활용되며, 정규표현식을 지원해 매우 강력한 패턴 매칭이 가능하다.

그림 7.2: grep 명령어 구조

이 장에서는 grep의 기본적인 패턴 검색부터 시작해서, 다양한 옵션을 활용한 정교한 검색, 그리고 find 명령어와의 조합을 통한 강력한 파일 시스템 탐색 방법까지 다룰 것이다. 마지막에는 AI 도구들이 어떻게 이런 복잡한 명령어들을 더 쉽게 만들어주는지도 살펴보겠다.

7.1.1 기본 패턴 검색

소프트웨어 프로젝트의 오류 로그 파일을 예제로 살펴보자. “logs” 디렉토리에 있는 시스템 로그로 작업해보겠다.

$ cd
$ cd filesystem/Users/nelle/logs
$ cat system.log

2024-03-15 09:15:23 INFO Server started successfully
2024-03-15 09:16:45 ERROR Connection timeout: database server not responding
2024-03-15 09:17:02 WARNING Memory usage at 85%
2024-03-15 09:18:11 ERROR Failed to connect to API endpoint
2024-03-15 09:19:33 INFO User login: nelle@example.com
2024-03-15 09:20:55 ERROR NullPointerException in module payment
2024-03-15 09:21:17 INFO Cache cleared successfully
2024-03-15 09:22:39 WARNING Disk space running low
2024-03-15 09:23:01 ERROR Connection refused: port 3306
주의영원히 혹은 5년

원본 하이쿠에 링크를 걸지 않았는데 이유는 Salon 사이트에 더 이상 보이는 것 같지 않아서다. Jeff Rothenberg가 말했듯이, “디지털 정보는 어느 것이 먼저 오든 영원한 영속성을 가지거나 혹은 5년이다.” 운이 좋은 경우 인기 콘텐트는 종종 백업된다. (Marwick 기타, 2018) (Boettiger, 2015)

오류를 나타내는 “ERROR”를 포함하는 행을 찾아 보자.

$ grep ERROR system.log

2024-03-15 09:16:45 ERROR Connection timeout: database server not responding
2024-03-15 09:18:11 ERROR Failed to connect to API endpoint
2024-03-15 09:20:55 ERROR NullPointerException in module payment
2024-03-15 09:23:01 ERROR Connection refused: port 3306

여기서 ERROR가 우리가 찾기 원하는 패턴이다. grep 명령어는 파일 내용을 살펴보며 지정된 패턴과 일치하는 부분을 찾아낸다. 사용법은 간단하다: grep을 입력한 후, 찾으려는 패턴을 지정하고, 마지막에 검색할 파일명(또는 여러 파일명)을 적어주면 된다.

결과로 “ERROR”를 포함하는 네 개의 행이 출력되었다. 이를 통해 시스템에 어떤 문제가 발생했는지 빠르게 파악할 수 있다.

다른 패턴을 시도해보자. 이번에는 “Connection”을 찾아보겠다.

$ grep Connection system.log

2024-03-15 09:16:45 ERROR Connection timeout: database server not responding
2024-03-15 09:23:01 ERROR Connection refused: port 3306

이번에는 “Connection” 문자열을 포함한 두 행이 출력되었다. 모두 데이터베이스 연결 문제와 관련된 오류임을 알 수 있다.

완전한 단어만 검색하고 싶을 때는 -w 옵션을 사용한다. 예를 들어 “port”라는 단어만 찾고 “support”나 “transport”는 제외하려면:

$ grep -w port system.log

2024-03-15 09:23:01 ERROR Connection refused: port 3306

이제 여러 단어로 이루어진 문구를 찾아보자. 공백이 포함된 검색어는 인용부호로 감싸야 한다:

$ grep -w "database server" system.log

2024-03-15 09:16:45 ERROR Connection timeout: database server not responding

지금까지는 단일 단어를 검색할 때 인용부호가 반드시 필요하지 않았다. 하지만 여러 단어로 이루어진 문구를 검색할 때는 인용부호를 사용하는 것이 좋다. 이렇게 하면 검색어와 파일명을 더 명확하게 구분할 수 있다. 앞으로의 예제에서는 일관성을 위해 인용부호를 사용하겠다.

또다른 유용한 옵션은 -n으로, 매칭되는 행에 번호를 붙여 출력한다.

$ grep -n "server" system.log

1:2024-03-15 09:15:23 INFO Server started successfully
2:2024-03-15 09:16:45 ERROR Connection timeout: database server not responding

위 결과에서 1, 2번째 행에 ’server’가 포함된 것을 확인할 수 있다.

7.1.2 고급 옵션과 정규표현식

다른 유닉스 명령어와 마찬가지로 여러 옵션을 함께 사용할 수 있다. 예를 들어 단어 “the”를 포함하는 행을 찾을 때, 완전한 단어만 검색하는 -w 옵션과 행 번호를 표시하는 -n 옵션을 함께 사용해보자:

$ grep -n -w "the" haiku.txt

2:Is not the true Tao, until
6:and the presence of absence:

이제 -i 옵션을 사용해서 대소문자를 구분하지 않고 검색해보자.

$ grep -n -w -i "the" haiku.txt

1:The Tao that is seen
2:Is not the true Tao, until
6:and the presence of absence:

이번에는 -v 옵션을 사용해서 검색 결과를 반전시켜보자. 즉, 단어 “the”를 포함하지 않는 행들을 출력한다.

$ grep -n -w -v "the" haiku.txt

1:The Tao that is seen
3:You bring fresh toner.
4:
5:With searching comes loss
7:"My Thesis" not found.
8:
9:Yesterday it worked
10:Today it is not working
11:Software is like that.

grep 명령어에는 매우 다양한 옵션이 있다. 더 자세한 정보가 필요하면 grep --help 명령어로 도움말을 확인할 수 있다.

7.1.3 단어 경계와 정확한 검색

많은 개발자들이 grep 사용 중 마주치는 문제 중 하나가 단어 경계다. 예를 들어, 코드에서 “count” 변수를 찾고 싶어서 grep "count" app.js를 실행하면 “account”, “counter”, “discount” 같은 단어들도 함께 나온다. 이럴 때 사용하는 옵션이 -w(단어 경계)다.

앞서 시스템 로그에서 “port”를 찾았을 때도 같은 원리가 적용된다. grep -w "port" system.log를 사용하면 “support”나 “transport” 같은 단어는 제외되고 정확히 “port”라는 단어만 찾는다. -w 옵션은 완전한 단어로서만 매칭하기 때문에, 다른 단어의 일부분으로 포함된 경우는 무시한다.

이는 프로그래밍에서 변수명이나 함수명을 정확히 찾을 때 특히 유용하다. 예를 들어 “is”라는 변수를 찾을 때 grep -w "is" code.js를 사용하면 “dismiss”나 “this” 같은 단어는 제외되고 정확히 “is” 변수만 찾아낸다.

주의와일드카드(Wildcards)

grep의 진정한 힘은 옵션에서 나오지 않고, 패턴에 와일드카드를 포함할 수 있다는 사실에서 나온다. (기술적 명칭은 정규 표현식(regular expressions)이고, “grep” 명령어의 “re”가 정규표현식을 나타낸다.) 정규 표현식은 복잡하기도 하지만 강력하기도 하다. 복잡한 검색을 하고자 한다면, 소프트웨어 카펜트리 웹사이트에서 정규표현식을 참고한다. 맛보기로, 다음과 같이 두번째 위치에 ’o’를 포함한 행을 찾을 수 있다.

$ grep -E '^.o' haiku.txt

You bring fresh toner.
Today it is not working
Software is like that.

-E 옵션을 사용하고 패턴을 인용부호로 감싸서 쉘이 특수문자를 먼저 해석하지 못하게 한다. (예를 들어, 패턴에 ‘*’가 포함되면 grep이 실행되기 전에 쉘이 와일드카드를 전개하려 한다.) 패턴에서’^‘는 행의 시작을 의미하고,’.’는 임의의 한 문자를 매칭하며(쉘의 ’?’와 유사), ’o’는 문자 그대로 ’o’를 찾는다.

7.1.4 데이터 분석 grep 활용

실제 데이터 분석 프로젝트에서는 단순한 텍스트 검색을 넘어서 더 복잡한 파이프라인을 구성해야 하는 경우가 많다. 생태학자 넬이 야생동물 관측 데이터를 분석하는 과정을 통해 grep이 어떻게 다른 유닉스 도구들과 조합되는지 살펴보자.

데이터는 다음과 같이 CSV 형태로 저장되어 있다.

2013-11-05,deer,5
2013-11-05,rabbit,22  
2013-11-05,raccoon,7
2013-11-06,rabbit,19
2013-11-06,deer,2

넬은 특정 동물(예: rabbit)의 일자별 관측 데이터만 추출하고 싶어한다. 매번 수동으로 하기에는 너무 번거로울 것 같아서 스크립트로 자동화하기로 했다.

이 문제를 단계별로 해결해보자. 먼저 grep -w rabbit -r ./data로 모든 파일에서 rabbit이 포함된 행을 재귀적으로 검색한다. -w 옵션을 사용하는 이유는 “rabbit-like” 같은 복합어는 제외하고 정확히 “rabbit”이라는 단어만 찾기 위해서다. 그 다음 cut -d : -f 2로 파일명 부분을 제거하고, cut -d , -f 1,3로 날짜와 개체수 열만 추출한다.

최종적으로 grep -w $1 -r $2 | cut -d : -f 2 | cut -d , -f 1,3 > $1.txt 형태의 파이프라인이 완성된다. 이 스크립트를 bash count-species.sh rabbit ./data로 실행하면 rabbit의 날짜별 관측 데이터가 자동으로 rabbit.txt 파일에 저장된다.

7.1.5 코딩에서 grep 활용

데이터 분석뿐만 아니라 소프트웨어 개발에서도 grep은 코드 분석과 리팩토링에 핵심적인 역할을 한다. 대규모 코드베이스에서는 키워드 사용 빈도나 패턴을 분석해야 하는 경우가 자주 발생한다.

예를 들어, 한 팀에서 비동기 처리 방식에 대한 논쟁이 벌어졌다고 하자. async/await 패턴과 Promise, callback 중에서 어느 방식이 더 많이 사용되고 있는지 데이터로 확인하고 싶어한다.

여러 JavaScript 파일이 합쳐진 source_code.js 파일이 있다고 하자. 각 키워드의 사용 빈도를 확인하는 스크립트를 작성해보자:

for keyword in async await Promise callback
do
    echo "$keyword 사용 횟수:"
    grep -ow $keyword source_code.js | wc -l
done

여기서 -o 옵션은 매칭된 부분만 출력하고, -w 옵션은 완전한 단어만 찾도록 한다. 이렇게 하면 “asyncFunction” 같은 단어는 제외되고 순수한 “async” 키워드만 카운트한다. 결과를 파이프로 wc -l에 전달하면 총 개수를 구할 수 있다.

grep -c 옵션을 사용할 수도 있지만, 이는 매칭되는 행의 개수만 센다. 한 행에 같은 키워드가 여러 번 나타나는 경우 정확한 개수가 나오지 않으므로, -o 옵션과 wc -l 조합이 더 정확하다.

7.2 find 명령어

grep이 파일 안의 내용을 검색하는 도구라면, find 명령어는 파일과 디렉토리 자체를 찾아주는 도구다. find 명령어는 매우 다양한 옵션을 제공한다.

그림 7.3: find 명령어 구조

기본 사용법을 이해하기 위해 다음과 같은 디렉토리 구조를 예제로 살펴보자. Nelle 박사 writing 디렉토리 안에는 다음과 같은 구조로 되어 있다.

그림 7.4: find 찾기 예제 파일 구조
  • haiku.txt: 프로그래밍 하이쿠가 담긴 텍스트 파일
  • thesis 디렉토리: 논문 초고 empty-draft.md 파일 (아직 비어있음!)
  • data 디렉토리: one.txt, two.txt 등 데이터 파일들
  • tools 디렉토리: format, stats 프로그램과 old 하위 디렉토리

가장 기본적인 find . 명령어를 실행해보자.

$ find .

.
./data
./data/one.txt
./data/LittleWomen.txt
./data/two.txt
./tools
./tools/format
./tools/old
./tools/old/oldtool
./tools/stats
./haiku.txt
./thesis
./thesis/empty-draft.md

여기서 .은 현재 작업 디렉토리를 의미하며, 검색을 시작할 기준점이 된다. find 명령어는 현재 디렉토리와 그 아래 모든 하위 디렉토리에서 파일과 디렉토리를 모두 찾아서 나열해준다. 언뜻 보기에는 별로 유용해 보이지 않을 수 있지만, find 명령어에는 결과를 필터링할 수 있는 다양한 옵션이 있다. 여기서는 가장 자주 사용되는 몇 가지만 살펴보겠다.

첫 번째 옵션은 -type d로 “디렉토리만” 찾겠다는 의미다. 예상대로 find의 출력에는 현재 디렉토리(.)를 포함해서 총 5개의 디렉토리가 나온다.

$ find . -type d

./
./data
./thesis
./tools
./tools/old

find 명령어의 출력 순서는 예측할 수 없다는 점에 주의하자. -type d에서 -type f로 옵션을 변경하면, 대신에 모든 파일 목록이 나온다.

$ find . -type f

./haiku.txt
./tools/stats
./tools/old/oldtool
./tools/format
./thesis/empty-draft.md
./data/one.txt
./data/LittleWomen.txt
./data/two.txt

이제 이름으로 매칭을 하자:

$ find . -name *.txt

./haiku.txt

모든 텍스트 파일을 찾을 것으로 기대했지만, ./haiku.txt만 출력된다. 문제는 명령어를 실행하기 전에 쉘이 * 같은 와일드카드를 먼저 전개하기 때문이다. 현재 디렉토리에서 *.txt 패턴이 haiku.txt로 전개되므로, 실제로는 다음과 같은 명령어가 실행된다.

$ find . -name haiku.txt

find 명령어는 요청받은 대로만 정확히 수행한다. 예상과 다른 결과가 나온 이유는 명령어를 잘못 작성했기 때문이다.

원하는 결과를 얻으려면 grep에서 했던 것처럼 패턴을 보호해야 한다. *.txt를 작은따옴표로 감싸서 쉘이 와일드카드 *를 전개하지 못하게 하자. 이렇게 하면 find 명령어가 전개된 파일명 haiku.txt가 아닌 원래 패턴 *.txt를 받게 된다:

$ find . -name '*.txt'

./data/one.txt
./data/LittleWomen.txt
./data/two.txt
./haiku.txt
주의목록화(Listing) vs. 찾기(Finding)

적절한 옵션을 사용하면 lsfind 명령어로 비슷한 작업을 수행할 수 있다. 하지만 일반적으로 ls는 현재 디렉토리의 파일을 단순히 나열하는 반면, find는 복잡한 조건으로 파일을 검색하는 데 특화되어 있다.

7.3 조합의 힘

앞에서 언급했듯이, 명령-라인(command-line)의 힘은 도구를 조합하는데 있다. 파이프로 어떻게 조합하는지를 살펴봤으니, 또 다른 기술을 찾아보자. 방금 보았듯이, find . -name '*.txt' 명령어는 현재 디렉토리 및 하위 디렉토리에 있는 모든 텍스트 파일 목록을 보여준다. 어떻게 하면 wc -l 명령어와 조합해서 모든 파일의 행을 개수할 수 있을까?

가장 간단한 방법은 $() 내부에 find 명령어를 위치시키는 것이다.

$ wc -l $(find . -name '*.txt')

11 ./haiku.txt
300 ./data/two.txt
21022 ./data/LittleWomen.txt
70 ./data/one.txt
21403 total

쉘이 이 명령어를 실행할 때, 먼저 $() 안의 내용을 실행한다. 그 다음 $() 부분을 명령어 실행 결과로 교체한다. find의 출력이 4개 파일명(./data/one.txt, ./data/LittleWomen.txt, ./data/two.txt, ./haiku.txt)이므로, 쉘은 다음과 같은 명령어를 구성한다:

$ wc -l ./data/one.txt ./data/LittleWomen.txt ./data/two.txt ./haiku.txt

이것이 바로 우리가 원하던 명령어다. 이런 치환 방식은 *이나 ? 같은 와일드카드가 확장될 때 쉘이 하는 작업과 동일하다. 다만 여기서는 우리만의 “와일드카드”로 원하는 임의의 명령어를 사용할 수 있다.

findgrep을 함께 사용하는 것은 매우 일반적인 패턴이다. 첫 번째로 find가 특정 조건의 파일을 찾고, 두 번째로 grep이 그 파일들 안에서 특정 패턴을 찾는다. 예를 들어, 상위 디렉토리의 모든 .pdb 파일에서 “FE” 문자열을 검색해서 철(FE) 원자를 포함하는 PDB 파일을 찾을 수 있다:

$ grep "FE" $(find .. -name '*.pdb')

../data/pdb/heme.pdb:ATOM     25 FE           1      -0.924   0.535  -0.518

7.3.1 복합 검색 조건 활용

파일 시스템에서 여러 조건을 조합한 검색이 필요한 경우가 종종 있다. 예를 들어, 프로젝트에서 특정 패턴의 파일명을 가지면서 동시에 특정 내용은 제외하고 싶은 상황이다.

grep-v 옵션은 패턴 매칭을 반전시켜서 패턴과 일치하지 않는 결과만 출력한다. 이를 파이프라인과 조합하면 매우 유용한 필터링이 가능하다.

실제 예시로 /data 폴더에서 s.txt로 끝나는 파일들(animals.txt, planets.txt 등) 중에서 net 단어가 파일명에 포함되지 않은 것만 찾고 싶다고 하자:

find data -name '*s.txt' | grep -v net

이 명령은 두 단계로 작동한다. 먼저 find data -name '*s.txt'가 조건에 맞는 모든 파일을 찾고, 그 결과를 파이프로 grep -v net에 전달하여 파일명에 “net”이 포함된 것들을 제외한다.

여기서 중요한 점은 와일드카드 패턴 '*s.txt'을 인용부호로 감싼 것이다. 인용부호가 없으면 쉘이 현재 디렉토리에서 패턴을 먼저 전개하려 시도하므로, find 명령어가 의도한 대로 작동하지 않을 수 있다. 반면 grep -v "temp" $(find data -name '*s.txt')처럼 사용하면 파일명이 아닌 파일 내용에서 “temp”를 제외하는 다른 동작이 된다.

주의바이너리 파일(Binary File)

지금까지는 텍스트 파일 검색에만 집중했다. 그렇다면 데이터가 이미지나 데이터베이스, 또는 다른 형식으로 저장되어 있다면 어떻게 할까?

첫 번째 방법은 grep 같은 도구를 확장해서 텍스트가 아닌 형식도 처리할 수 있게 하는 것이다. 하지만 이런 접근법은 현실적이지 않다. 지원해야 할 파일 형식이 너무 많기 때문이다.

두 번째 방법은 데이터를 텍스트로 변환하거나, 데이터에서 텍스트 부분을 추출하는 것이다. 각 데이터 형식마다 전용 도구 하나씩만 개발하면 되므로 가장 현실적인 접근법이다. 이 방법은 간단한 작업을 쉽게 만들어주지만, 복잡한 작업은 보통 불가능하다.

예를 들어 grep을 활용해서 이미지 파일에서 크기 정보를 추출하는 프로그램은 상대적으로 쉽게 만들 수 있다. 하지만 수식이 들어있는 엑셀 파일에서 특정 값을 찾는 작업은 어떨까?

세 번째 방법은 쉘과 텍스트 처리 도구의 한계를 인정하고 R이나 파이썬 같은 프로그래밍 언어를 사용하는 것이다. 쉘로 처리하기 어려운 지점에 도달했다면 무리하지 말자. R이나 파이썬을 비롯한 많은 언어들이 유닉스 철학을 받아들었다. 모방이야말로 진정한 찬사다.

유닉스 쉘은 지금 사용하는 대부분의 사람보다 나이가 많다. 그토록 오랫동안 생존한 이유는 지금까지 만들어진 가장 생산성이 높은 프로그래밍 환경 중 하나 혹은 아마도 가장 생산성 높은 프로그래밍 환경이기 때문이다. 구문이 암호스러울 수도 있지만, 숙달한 사람은 다양한 명령어를 대화하듯이 실험하고 나서, 본인 작업을 자동화하는데 학습한 것을 사용한다. 그래픽 사용자 인터페이스(GUI)가 처음에는 더 좋을 수 있지만, 여전히 쉘이 최강이다.

화이트헤드(Alfred North Whitehead) 박사는 1911년 이렇게 말했다: “문명은 생각 없이 수행할 수 있는 중요한 작업의 수를 늘려가며 발전한다.” (Civilization advances by extending the number of important operations which we can perform without thinking about them.)

7.3.2 데이터 파일 크기 비교

연구자 민수는 여러 실험에서 생성된 데이터 파일들의 크기를 비교하고 싶어한다. 모든 데이터 파일은 .dat 확장자를 가지고 있으며, 파일의 행 수로 데이터량을 측정하려고 한다.

$ wc -l $(find . -name '*.dat') | sort -n

이 명령어가 실행되는 과정을 살펴보자:

먼저 find . -name '*.dat' 부분이 현재 디렉토리와 하위 디렉토리에서 확장자가 .dat인 모든 파일을 찾는다. 이 결과가 $(...) 명령 치환을 통해 wc -l의 인자로 전달되어, 각 파일의 행 수를 계산한다. 마지막으로 sort -n이 결과를 숫자 순으로 정렬하여, 민수는 가장 작은 데이터 파일부터 가장 큰 데이터 파일 순으로 정렬된 목록을 얻을 수 있다.

7.3.3 보안 감사 파일 추적

시스템 관리자 현지는 보안 감사를 위해 특정 사용자가 최근에 수정한 파일들을 추적해야 한다. find 명령어는 파일 이름뿐만 아니라 파일의 다양한 속성으로도 검색할 수 있어 이런 작업에 매우 유용하다.

예를 들어, 지난 24시간 동안 ahmed 사용자가 수정한 모든 파일을 찾으려면 다음과 같이 여러 조건을 조합할 수 있다:

$ find ./ -type f -mtime -1 -user ahmed

이 명령어는 세 가지 조건을 동시에 만족하는 파일을 찾는다: - -type f: 일반 파일만 (디렉토리 제외) - -mtime -1: 1일 이내에 수정된 파일 (음수는 ’이내’를 의미) - -user ahmed: 소유자가 ahmed인 파일

-mtime에서 음수를 사용하는 이유는 ‘그 시간보다 적은’, 즉 ’최근’을 의미하기 때문이다. 양수를 사용하면 ’정확히 그 시간 전’을 의미하게 되어 원하는 결과를 얻기 어렵다.

7.4 AI 시대 검색

전통적으로 유닉스 명령어를 마스터하려면 수많은 옵션과 플래그를 암기해야 했다. find . -name "*.txt" -mtime -7 -exec grep -l "error" {} \; 같은 명령어는 문법을 정확히 알아야만 작성할 수 있었다. 하지만 AI 도구들의 등장으로 이 모든 것이 바뀌었다.

이제는 Claude Code, GitHub Copilot CLI, Shell GPT 같은 도구에게 자연어로 “최근 7일 내 수정된 텍스트 파일에서 ‘error’ 포함 파일 찾기”라고 요청하면 된다. AI가 복잡한 명령어를 자동으로 생성해주기 때문이다.

더 복잡한 작업도 마찬가지다. “모든 JavaScript 파일에서 async 함수가 몇 개인지 세어줘”라고 요청하면, AI는 find . -name "*.js" -exec grep -c "async function" {} + | awk '{sum += $1} END {print sum}' 같은 정교한 파이프라인을 자동으로 생성한다.

이런 변화는 단순히 편의성만 제공하는 것이 아니다. 개발자들이 복잡한 문법을 외우는 데 시간을 쓰는 대신, 실제 문제 해결과 창의적 작업에 집중할 수 있게 해준다. 특히 초보자에게는 유닉스 명령어의 진입 장벽을 대폭 낮춰주고, 전문가에게는 더 복잡하고 정교한 작업을 빠르게 수행할 수 있는 도구가 되어준다.