Linux에서 디렉토리 트리를 탐색하는 방법

게시 됨: 2022-07-21
bash 프롬프트를 표시하는 Linux 노트북
Fatmawati achmad zaenuri/Shutterstock.com

Linux의 디렉터리를 사용하면 파일을 별개의 별도 컬렉션으로 그룹화할 수 있습니다. 단점은 반복적인 작업을 수행하기 위해 디렉토리에서 디렉토리로 이동하는 것이 지루해진다는 것입니다. 자동화하는 방법은 다음과 같습니다.

디렉토리에 관한 모든 것

Linux를 처음 접했을 때 배우는 첫 번째 명령은 아마도 ls 이지만 cd 는 그 뒤를 따르지 않을 것입니다. 디렉토리와 그 주위를 이동하는 방법, 특히 중첩된 하위 디렉토리를 이해하는 것은 Linux가 자체적으로 구성하는 방식과 자신의 작업을 파일, 디렉토리 및 하위 디렉토리로 구성하는 방법을 이해하는 기본적인 부분입니다.

Linux 디렉토리 구조, 설명
관련 Linux 디렉토리 구조, 설명

디렉토리 트리의 개념과 디렉토리 사이를 이동하는 방법을 이해하는 것은 Linux 환경에 익숙해지면서 통과하는 많은 작은 이정표 중 하나입니다. 경로와 함께 cd 를 사용하면 해당 디렉토리로 이동합니다. cd ~ 또는 cd 와 같은 단축키는 홈 디렉토리로 돌아가게 하고 cd .. 는 디렉토리 트리에서 한 단계 위로 이동합니다. 단순한.

그러나 디렉토리 트리의 모든 디렉토리에서 명령을 실행하는 똑같이 간단한 방법은 없습니다. 그 기능을 달성할 수 있는 다른 방법이 있지만 그 목적을 위한 표준 Linux 명령은 없습니다.

ls 와 같은 일부 명령에는 재귀적 으로 작동하도록 하는 명령줄 옵션이 있습니다. 즉, 한 디렉터리에서 시작하여 해당 디렉터리 아래의 전체 디렉터리 트리를 통해 체계적으로 작동합니다. ls 의 경우 -R (재귀) 옵션입니다.

재귀를 지원하지 않는 명령을 사용해야 하는 경우 재귀 기능을 직접 제공해야 합니다. 방법은 다음과 같습니다.

관련: 알아야 할 37가지 중요한 Linux 명령

트리 명령

tree 명령은 당면한 작업에 도움이 되지 않지만 디렉토리 트리의 구조를 쉽게 볼 수 있게 해줍니다. 그것은 우리가 디렉토리 트리를 구성하는 디렉토리와 서브디렉토리의 즉각적인 개요와 트리에서의 상대적 위치를 얻을 수 있도록 터미널 창에 트리를 그립니다.

tree 를 설치해야 합니다.

Ubuntu에서는 다음을 입력해야 합니다.

 sudo apt 설치 트리 

우분투에 트리 설치

Fedora에서 다음을 사용합니다.

 sudo dnf 설치 트리 

Fedora에 트리 설치

Manjaro에서 명령은 다음과 같습니다.

 sudo pacman - 사이 트리 

Manjaro에 나무 설치

매개변수 없이 tree 를 사용하면 현재 디렉토리 아래에 트리가 그려집니다.

 나무 

현재 디렉토리에서 트리 실행

명령줄에서 tree 경로를 전달할 수 있습니다.

 나무 작업 

지정된 디렉토리에서 트리 실행

-d (디렉토리) 옵션은 파일을 제외하고 디렉토리만 표시합니다.

 나무 -d 작업 

트리를 실행하고 디렉토리만 표시

이것은 디렉토리 트리의 구조를 명확하게 볼 수 있는 가장 편리한 방법입니다. 여기에 표시된 디렉토리 트리는 다음 예에서 사용된 것입니다. 5개의 텍스트 파일과 8개의 디렉토리가 있습니다.

ls에서 디렉토리를 트래버스로 출력을 구문 분석하지 마십시오.

첫 번째 생각은 ls 가 디렉토리 트리를 재귀적으로 탐색할 수 있다면 ls 를 사용하여 그 작업을 수행하고 디렉토리를 구문 분석하고 일부 작업을 수행하는 다른 명령으로 출력을 파이프하는 것이 어떻겠습니까?

ls 의 출력을 구문 분석하는 것은 나쁜 습관으로 간주됩니다. 모든 종류의 이상한 문자를 포함하는 파일 및 디렉터리 이름을 만드는 Linux의 기능 때문에 일반적이고 보편적으로 올바른 구문 분석기를 만드는 것이 매우 어려워집니다.

이렇게 터무니없는 디렉토리 이름을 고의로 만들지는 않겠지만 스크립트나 응용 프로그램의 실수가 있을 수 있습니다.

이상한 디렉토리 이름

합법적이지만 제대로 간주되지 않는 파일 및 디렉터리 이름을 구문 분석하면 오류가 발생하기 쉽습니다. ls 의 출력 해석에 의존하는 것보다 더 안전하고 훨씬 더 강력한 다른 방법을 사용할 수 있습니다.

찾기 명령 사용

find 명령에는 재귀 기능이 내장되어 있으며 우리를 위해 명령을 실행할 수도 있습니다. 이를 통해 강력한 단일 라이너를 구축할 수 있습니다. 미래에 사용하고 싶은 것이 있다면 한 줄짜리를 별칭이나 쉘 함수로 바꿀 수 있습니다.

이 명령은 디렉터리 트리를 재귀적으로 반복하여 디렉터리를 찾습니다. 디렉토리를 찾을 때마다 디렉토리 이름을 출력하고 해당 디렉토리 내에서 검색을 반복합니다. 한 디렉토리 검색을 완료하면 해당 디렉토리를 종료하고 상위 디렉토리에서 검색을 재개합니다.

 작업 유형 d -execdir 찾기 echo "In:" {} \; 

find 명령을 사용하여 재귀적으로 디렉토리 찾기

디렉토리가 나열된 순서로 트리를 통해 검색이 진행되는 방식을 볼 수 있습니다. tree 명령의 출력을 find one-liner의 출력과 비교하면 find가 하위 디렉터리가 없는 디렉터리에 도달할 때까지 각 디렉터리와 하위 디렉터리를 차례로 검색하는 방법을 find 있습니다. 그런 다음 한 수준 위로 돌아가서 해당 수준에서 검색을 다시 시작합니다.

다음은 명령을 구성하는 방법입니다.

  • 찾기 : find 명령입니다.
  • work : 검색을 시작할 디렉토리. 경로가 될 수 있습니다.
  • -type d : 디렉토리를 찾고 있습니다.
  • -execdir : 찾은 각 디렉토리에서 명령을 실행할 것입니다.
  • echo "In:" {} : 이것은 명령입니다. 우리는 단순히 디렉토리 이름을 터미널 창에 에코하고 있습니다. "{}"는 현재 디렉터리의 이름을 보유합니다.
  • \; : 명령을 종료할 때 사용하는 세미콜론입니다. Bash가 직접 해석하지 않도록 백슬래시로 이스케이프 처리해야 합니다.

약간의 변경으로 find 명령이 검색 단서와 일치하는 파일을 반환하도록 할 수 있습니다. -name 옵션과 검색 단서를 포함해야 합니다. 이 예에서는 "*.txt"와 일치하는 텍스트 파일을 찾고 해당 이름을 터미널 창에 표시합니다.

 작업 찾기 -이름 "*.txt" -type f -execdir echo "찾음:" {} \; 

find 명령을 사용하여 재귀적으로 파일 찾기

파일 또는 디렉토리를 검색할지 여부는 달성하려는 항목에 따라 다릅니다. 각 디렉토리 내 에서 명령을 실행하려면 -type d 를 사용하십시오. 일치하는 각 파일 에 대해 명령을 실행하려면 -type f 를 사용하십시오.

이 명령은 시작 디렉터리와 하위 디렉터리에 있는 모든 텍스트 파일의 줄 수를 계산합니다.

 작업 찾기 -이름 "*.txt" -type f -execdir wc -l {} \; 

wc 명령과 함께 찾기 사용

관련: 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 

recurse.sh 스크립트를 실행 가능하게 만들기

스크립트는 dotglobnullglob 의 두 가지 셸 옵션을 설정합니다.

dotglob 설정은 마침표 " 로 시작하는 파일 및 디렉터리 이름을 의미합니다 . "는 와일드카드 검색어가 확장되면 반환됩니다. 이는 검색 결과에 숨겨진 파일과 디렉토리를 포함한다는 의미입니다.

nullglob 설정은 결과를 찾지 못하는 검색 패턴이 비어 있거나 null 문자열로 처리됨을 의미합니다. 검색 용어 자체를 기본값으로 사용하지 않습니다. 즉, 별표 와일드카드 " * "를 사용하여 디렉토리의 모든 항목을 검색하지만 결과가 없으면 별표가 포함된 문자열 대신 null 문자열을 받게 됩니다. 이렇게 하면 스크립트가 실수로 "*"라는 디렉토리를 열려고 하거나 "*"를 파일 이름으로 취급하는 것을 방지할 수 있습니다.

다음으로 recursive 라는 함수를 정의합니다. 여기서 흥미로운 일이 발생합니다.

current_dirdir_or_file 이라는 두 개의 변수가 선언되었습니다. 이들은 지역 변수이며 함수 내에서만 참조할 수 있습니다.

$1 이라는 변수도 함수 내에서 사용됩니다. 이것은 호출될 때 함수에 전달되는 첫 번째(유일한) 매개변수입니다.

입문서: Bash 루프: for, while, until
관련 입문서: Bash 루프: for, while 및 until

스크립트는 두 개의 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 작업 

가장 깊은 곳에서 가장 얕은 곳으로 디렉토리 처리

이번에는 디렉토리에 가장 깊은 수준에서 먼저 적용된 명령이 있으며 트리의 분기를 백업합니다. 스크립트에 매개변수로 전달된 디렉토리가 마지막으로 처리됩니다.

더 깊은 디렉토리를 먼저 처리하는 것이 중요하다면 이것이 당신이 할 수 있는 방법입니다.

재귀가 이상하다

자신의 전화로 자신에게 전화를 걸고 다음에 만날 때 자신에게 전할 메시지를 반복해서 남기는 것과 같습니다.

이점을 이해하기 전에 약간의 노력이 필요할 수 있지만, 이해하면 어려운 문제를 해결하는 프로그래밍 방식으로 우아한 방법임을 알게 될 것입니다.

관련: 프로그래밍에서 재귀란 무엇이며 어떻게 사용합니까?