Linux에서 디렉토리 트리를 탐색하는 방법
게시 됨: 2022-07-21
Linux의 디렉터리를 사용하면 파일을 별개의 별도 컬렉션으로 그룹화할 수 있습니다. 단점은 반복적인 작업을 수행하기 위해 디렉토리에서 디렉토리로 이동하는 것이 지루해진다는 것입니다. 자동화하는 방법은 다음과 같습니다.
디렉토리에 관한 모든 것
Linux를 처음 접했을 때 배우는 첫 번째 명령은 아마도 ls
이지만 cd
는 그 뒤를 따르지 않을 것입니다. 디렉토리와 그 주위를 이동하는 방법, 특히 중첩된 하위 디렉토리를 이해하는 것은 Linux가 자체적으로 구성하는 방식과 자신의 작업을 파일, 디렉토리 및 하위 디렉토리로 구성하는 방법을 이해하는 기본적인 부분입니다.
디렉토리 트리의 개념과 디렉토리 사이를 이동하는 방법을 이해하는 것은 Linux 환경에 익숙해지면서 통과하는 많은 작은 이정표 중 하나입니다. 경로와 함께 cd
를 사용하면 해당 디렉토리로 이동합니다. cd ~
또는 cd
와 같은 단축키는 홈 디렉토리로 돌아가게 하고 cd ..
는 디렉토리 트리에서 한 단계 위로 이동합니다. 단순한.
그러나 디렉토리 트리의 모든 디렉토리에서 명령을 실행하는 똑같이 간단한 방법은 없습니다. 그 기능을 달성할 수 있는 다른 방법이 있지만 그 목적을 위한 표준 Linux 명령은 없습니다.
ls
와 같은 일부 명령에는 재귀적 으로 작동하도록 하는 명령줄 옵션이 있습니다. 즉, 한 디렉터리에서 시작하여 해당 디렉터리 아래의 전체 디렉터리 트리를 통해 체계적으로 작동합니다. ls
의 경우 -R
(재귀) 옵션입니다.
재귀를 지원하지 않는 명령을 사용해야 하는 경우 재귀 기능을 직접 제공해야 합니다. 방법은 다음과 같습니다.
관련: 알아야 할 37가지 중요한 Linux 명령
트리 명령
tree
명령은 당면한 작업에 도움이 되지 않지만 디렉토리 트리의 구조를 쉽게 볼 수 있게 해줍니다. 그것은 우리가 디렉토리 트리를 구성하는 디렉토리와 서브디렉토리의 즉각적인 개요와 트리에서의 상대적 위치를 얻을 수 있도록 터미널 창에 트리를 그립니다.
tree
를 설치해야 합니다.
Ubuntu에서는 다음을 입력해야 합니다.
sudo apt 설치 트리
Fedora에서 다음을 사용합니다.
sudo dnf 설치 트리
Manjaro에서 명령은 다음과 같습니다.
sudo pacman - 사이 트리
매개변수 없이 tree
를 사용하면 현재 디렉토리 아래에 트리가 그려집니다.
나무
명령줄에서 tree
경로를 전달할 수 있습니다.
나무 작업
-d
(디렉토리) 옵션은 파일을 제외하고 디렉토리만 표시합니다.
나무 -d 작업
이것은 디렉토리 트리의 구조를 명확하게 볼 수 있는 가장 편리한 방법입니다. 여기에 표시된 디렉토리 트리는 다음 예에서 사용된 것입니다. 5개의 텍스트 파일과 8개의 디렉토리가 있습니다.
ls에서 디렉토리를 트래버스로 출력을 구문 분석하지 마십시오.
첫 번째 생각은 ls
가 디렉토리 트리를 재귀적으로 탐색할 수 있다면 ls
를 사용하여 그 작업을 수행하고 디렉토리를 구문 분석하고 일부 작업을 수행하는 다른 명령으로 출력을 파이프하는 것이 어떻겠습니까?
ls
의 출력을 구문 분석하는 것은 나쁜 습관으로 간주됩니다. 모든 종류의 이상한 문자를 포함하는 파일 및 디렉터리 이름을 만드는 Linux의 기능 때문에 일반적이고 보편적으로 올바른 구문 분석기를 만드는 것이 매우 어려워집니다.
이렇게 터무니없는 디렉토리 이름을 고의로 만들지는 않겠지만 스크립트나 응용 프로그램의 실수가 있을 수 있습니다.
합법적이지만 제대로 간주되지 않는 파일 및 디렉터리 이름을 구문 분석하면 오류가 발생하기 쉽습니다. ls
의 출력 해석에 의존하는 것보다 더 안전하고 훨씬 더 강력한 다른 방법을 사용할 수 있습니다.
찾기 명령 사용
find
명령에는 재귀 기능이 내장되어 있으며 우리를 위해 명령을 실행할 수도 있습니다. 이를 통해 강력한 단일 라이너를 구축할 수 있습니다. 미래에 사용하고 싶은 것이 있다면 한 줄짜리를 별칭이나 쉘 함수로 바꿀 수 있습니다.
이 명령은 디렉터리 트리를 재귀적으로 반복하여 디렉터리를 찾습니다. 디렉토리를 찾을 때마다 디렉토리 이름을 출력하고 해당 디렉토리 내에서 검색을 반복합니다. 한 디렉토리 검색을 완료하면 해당 디렉토리를 종료하고 상위 디렉토리에서 검색을 재개합니다.
작업 유형 d -execdir 찾기 echo "In:" {} \;
디렉토리가 나열된 순서로 트리를 통해 검색이 진행되는 방식을 볼 수 있습니다. tree
명령의 출력을 find
one-liner의 출력과 비교하면 find가 하위 디렉터리가 없는 디렉터리에 도달할 때까지 각 디렉터리와 하위 디렉터리를 차례로 검색하는 방법을 find
있습니다. 그런 다음 한 수준 위로 돌아가서 해당 수준에서 검색을 다시 시작합니다.
다음은 명령을 구성하는 방법입니다.
- 찾기 :
find
명령입니다. - work : 검색을 시작할 디렉토리. 경로가 될 수 있습니다.
- -type d : 디렉토리를 찾고 있습니다.
- -execdir : 찾은 각 디렉토리에서 명령을 실행할 것입니다.
- echo "In:" {} : 이것은 명령입니다. 우리는 단순히 디렉토리 이름을 터미널 창에 에코하고 있습니다. "{}"는 현재 디렉터리의 이름을 보유합니다.
- \; : 명령을 종료할 때 사용하는 세미콜론입니다. Bash가 직접 해석하지 않도록 백슬래시로 이스케이프 처리해야 합니다.
약간의 변경으로 find 명령이 검색 단서와 일치하는 파일을 반환하도록 할 수 있습니다. -name 옵션과 검색 단서를 포함해야 합니다. 이 예에서는 "*.txt"와 일치하는 텍스트 파일을 찾고 해당 이름을 터미널 창에 표시합니다.

작업 찾기 -이름 "*.txt" -type f -execdir echo "찾음:" {} \;
파일 또는 디렉토리를 검색할지 여부는 달성하려는 항목에 따라 다릅니다. 각 디렉토리 내 에서 명령을 실행하려면 -type d
를 사용하십시오. 일치하는 각 파일 에 대해 명령을 실행하려면 -type f
를 사용하십시오.
이 명령은 시작 디렉터리와 하위 디렉터리에 있는 모든 텍스트 파일의 줄 수를 계산합니다.
작업 찾기 -이름 "*.txt" -type f -execdir wc -l {} \;
관련: Linux에서 find 명령을 사용하는 방법
스크립트로 디렉토리 트리 탐색
스크립트 내에서 디렉토리를 탐색해야 하는 경우 스크립트 내에서 find
명령을 사용할 수 있습니다. 재귀 검색을 직접 수행해야 하거나 원할 경우에도 수행할 수 있습니다.
#!/bin/bash shopt -s dotglob nullglob 함수 재귀 { 로컬 current_dir dir_or_file $1의 current_dir에 대해; 하다 echo "디렉토리 명령:" $current_dir "$current_dir"/*의 dir_or_file용; 하다 if [[ -d $dir_or_file ]]; 그 다음에 재귀 "$dir_or_file" 또 다른 화장실 $dir_or_file 파이 완료 완료 } 재귀 "$1"
텍스트를 편집기에 복사하고 "recurse.sh"로 저장한 다음 chmod
명령을 사용하여 실행 가능하게 만듭니다.
chmod +x 재귀.sh
스크립트는 dotglob
및 nullglob
의 두 가지 셸 옵션을 설정합니다.
dotglob
설정은 마침표 " 로 시작하는 파일 및 디렉터리 이름을 의미합니다 .
"는 와일드카드 검색어가 확장되면 반환됩니다. 이는 검색 결과에 숨겨진 파일과 디렉토리를 포함한다는 의미입니다.
nullglob
설정은 결과를 찾지 못하는 검색 패턴이 비어 있거나 null 문자열로 처리됨을 의미합니다. 검색 용어 자체를 기본값으로 사용하지 않습니다. 즉, 별표 와일드카드 " *
"를 사용하여 디렉토리의 모든 항목을 검색하지만 결과가 없으면 별표가 포함된 문자열 대신 null 문자열을 받게 됩니다. 이렇게 하면 스크립트가 실수로 "*"라는 디렉토리를 열려고 하거나 "*"를 파일 이름으로 취급하는 것을 방지할 수 있습니다.
다음으로 recursive
라는 함수를 정의합니다. 여기서 흥미로운 일이 발생합니다.
current_dir
및 dir_or_file
이라는 두 개의 변수가 선언되었습니다. 이들은 지역 변수이며 함수 내에서만 참조할 수 있습니다.
$1
이라는 변수도 함수 내에서 사용됩니다. 이것은 호출될 때 함수에 전달되는 첫 번째(유일한) 매개변수입니다.
스크립트는 두 개의 for
루프를 사용합니다. 하나는 다른 루프 안에 중첩됩니다. 첫 번째(외부) for
루프는 두 가지 용도로 사용됩니다.
하나는 각 디렉토리에서 수행하려는 명령을 실행하는 것입니다. 여기서 우리가 하는 일은 디렉토리 이름을 터미널 창에 반영하는 것뿐입니다. 물론 명령이나 명령 시퀀스를 사용하거나 다른 스크립트 함수를 호출할 수 있습니다.
외부 for 루프가 하는 두 번째 작업은 찾을 수 있는 모든 파일 시스템 개체(파일 또는 디렉터리)를 확인하는 것입니다. 이것이 내부 for
루프의 목적입니다. 차례로, 각 파일 또는 디렉토리 이름은 dir_or_file
변수로 전달됩니다.
그런 다음 dir_or_file
변수가 디렉토리인지 확인하기 위해 if 문에서 테스트됩니다.
- 그렇다면 함수는 자신을 호출하고 디렉토리 이름을 매개변수로 전달합니다.
-
dir_or_file
변수가 디렉토리가 아니면 파일이어야 합니다. 파일에 적용하려는 모든 명령은if
문의else
절에서 호출할 수 있습니다. 동일한 스크립트 내에서 다른 함수를 호출할 수도 있습니다.
스크립트의 마지막 줄은 recursive
함수를 호출하고 첫 번째 명령줄 매개변수 $1
을 검색할 시작 디렉터리로 전달합니다. 이것이 전체 프로세스를 시작하는 것입니다.
스크립트를 실행해 봅시다.
./recurse.sh 작업
디렉토리가 탐색되고 스크립트의 각 디렉토리에서 명령이 실행될 지점은 "Directory command for:" 행으로 표시됩니다. 발견된 파일에는 행, 단어 및 문자를 계산하기 위해 wc
명령이 실행됩니다.
처리된 첫 번째 디렉토리는 "work"이고 그 뒤에 트리의 중첩된 각 디렉토리 분기가 옵니다.
흥미로운 점은 디렉토리별 명령을 내부 for 루프 위에서 아래로 이동하여 디렉토리가 처리되는 순서를 변경할 수 있다는 것입니다.
"Directory command for:" 줄을 내부 for
루프가 done
후로 이동해 보겠습니다.
#!/bin/bash shopt -s dotglob nullglob 함수 재귀 { 로컬 current_dir dir_or_file $1의 current_dir에 대해; 하다 "$current_dir"/*의 dir_or_file용; 하다 if [[ -d $dir_or_file ]]; 그 다음에 재귀 "$dir_or_file" 또 다른 화장실 $dir_or_file 파이 완료 echo "디렉토리 명령:" $current_dir 완료 } 재귀 "$1"
이제 스크립트를 한 번 더 실행하겠습니다.
./recurse.sh 작업
이번에는 디렉토리에 가장 깊은 수준에서 먼저 적용된 명령이 있으며 트리의 분기를 백업합니다. 스크립트에 매개변수로 전달된 디렉토리가 마지막으로 처리됩니다.
더 깊은 디렉토리를 먼저 처리하는 것이 중요하다면 이것이 당신이 할 수 있는 방법입니다.
재귀가 이상하다
자신의 전화로 자신에게 전화를 걸고 다음에 만날 때 자신에게 전할 메시지를 반복해서 남기는 것과 같습니다.
이점을 이해하기 전에 약간의 노력이 필요할 수 있지만, 이해하면 어려운 문제를 해결하는 프로그래밍 방식으로 우아한 방법임을 알게 될 것입니다.
관련: 프로그래밍에서 재귀란 무엇이며 어떻게 사용합니까?