n 레벨 만있는 서브 디렉토리 만 나열


58

Festival은 다음 예제 디렉토리 구조에 음성 팩 데이터를 저장합니다.

/usr/share/festival/voices/<language>/<voicepack name>

잠재적으로 수많은 하위 디렉토리 에서 모두 ls를 인쇄 하는 가장 간단한 단일 라이너 (바람직하게는 )를 사용하는 것은 무엇입니까 ?<voicepack name><language>

답변:


80

저는 Fedora를 사용하고 있으며이 음성 팩은 약간 다른 위치에 있습니다.

$ ls /usr/share/festival/lib/voices/*/ -1 | grep -vE "/usr|^$"
kal_diphone
ked_diphone
nitech_us_awb_arctic_hts
nitech_us_bdl_arctic_hts
nitech_us_clb_arctic_hts
nitech_us_jmk_arctic_hts
nitech_us_rms_arctic_hts
nitech_us_slt_arctic_hts

다음과 같이 수정하면됩니다.

$ ls /usr/share/festival/voices/*/ -1 | grep -vE "/usr|^$"

찾기 사용

ls이 매너에서 사용 하는 것은 일반적으로 출력의 ls파싱이 어렵 기 때문에 눈살을 찌푸 립니다. 다음 find과 같이 명령 을 사용하는 것이 좋습니다 .

$ find /usr/share/festival/lib/voices -maxdepth 2 -mindepth 2 \
    -type d -exec basename {} \;
nitech_us_awb_arctic_hts
nitech_us_bdl_arctic_hts
nitech_us_slt_arctic_hts
nitech_us_jmk_arctic_hts
nitech_us_clb_arctic_hts
nitech_us_rms_arctic_hts
ked_diphone
kal_diphone

찾기 및 기본 이름의 세부 사항

이 명령은이 디렉토리와 관련하여 정확히 2 레벨 깊이 인 파일의 전체 경로 목록을 생성하여 작동합니다.

/usr/share/festival/lib/voices

이 목록은 다음과 같습니다.

$ find /usr/share/festival/lib/voices -maxdepth 2 -mindepth 2 
/usr/share/festival/lib/voices/us/nitech_us_awb_arctic_hts
/usr/share/festival/lib/voices/us/nitech_us_bdl_arctic_hts
/usr/share/festival/lib/voices/us/nitech_us_slt_arctic_hts
/usr/share/festival/lib/voices/us/nitech_us_jmk_arctic_hts
/usr/share/festival/lib/voices/us/nitech_us_clb_arctic_hts
/usr/share/festival/lib/voices/us/nitech_us_rms_arctic_hts
/usr/share/festival/lib/voices/english/ked_diphone
/usr/share/festival/lib/voices/english/kal_diphon

그러나이 디렉토리의 마지막 부분 인 리프 노드를 원합니다. 그래서 우리는 basename그것을 파싱하기 위해 사용할 수 있습니다 :

$ basename /usr/share/festival/lib/voices/us/nitech_us_awb_arctic_hts
nitech_us_awb_arctic_hts

모두 합치면 find명령이 각 2 레벨 딥 디렉토리를 명령에 전달할 수 있습니다 basename. 표기법 basename {}은 이러한 기본 이름 변환을 수행하는 것입니다. -exec스위치 를 통해 전화를 찾습니다 .


롤, 거의 정확히 같은 대답, 좋은 마음과 모든 :).
terdon

+1-무엇을 알아낼 때 걸려 넘어지는 사람들을 -exec basename {}위해 여기서 설명해 주시겠습니까?
user66001 2009 년

@ user66001-설명이 충분하면 알려주세요.
slm

@ user66001-만족스러운 수준으로 문제를 해결하면 답변 중 하나를 수락 할 수 있습니다. 8-)
slm

1
find 명령은 99 %의 시간이 필요합니다. 최대 및 최소 제한이 핵심이었습니다. 예 : find ~/ -maxdepth 1 -mindepth 1 -type d | xargs du -csh | sort -h 크기에 따라 정렬 된 가장 큰 디렉토리를 찾습니다
oligofren

23

가장 쉬운 방법은

ls -d /usr/share/festival/voices/*/*

이것은 쉘에 의해 모든 하위 디렉토리로 확장 된 /usr/share/festival/voices/다음 각 하위 디렉토리의 내용으로 확장됩니다 .

findGNU와 일부 BSD와 같은 구현으로 제목에서 제안하는 특정 수준으로 만 내려 가려면 다음을 수행하십시오 .

find /usr/share/festival/voices/ -mindepth 2 -maxdepth 3 -type d

-type d하위 디렉토리 /usr/share/festival/voices/mindepth 2있지만 3 레벨 이하인 모든 디렉토리 ( )를 찾을 수 있습니다 ( maxdepth 3). 보낸 사람 man find:

   -maxdepth levels
          Descend at most levels (a non-negative integer) levels of direc
          tories below the command line arguments.  -maxdepth 0
           means only apply the tests and  actions  to  the  command  line
          arguments.

   -mindepth levels
          Do  not apply any tests or actions at levels less than levels (a
          non-negative integer).  -mindepth  1  means  process  all  files
          except the command line arguments.

예, 거울을 보는 것과 같습니다. 8-)
slm

+1 둘 다 2 표를 얻은 방법이 흥미 롭습니다. 크로스 투표 1 각 설명;) PS I 그래서 그냥 변경, 디렉토리 이름을 원 -type f하기 -type d바로,이 문제를 해결해야합니까? 또한의 목적에 대한 SLM의 응답에 대기-exec basename {}
user66001

@ user66001 예, -type d디렉토리를 찾습니다. 이것은 basename매우 좋은 생각입니다. 이름 만 인쇄하고 경로를 제거합니다. 이름 만 원한다고 가정하면 그렇게해야합니다. man basename또한 살펴보십시오 man dirname.
terdon

감사합니다 terdon-답변으로 표시하지 않아서 죄송합니다. SLM의 현재 버전 느꼈다 의이 그것을 필요로하는 사람들을 위해 더 많은 정보가 있습니다.
user66001 2009 년

1
@ user66001 우선, 당신은 절대적으로 맞습니다. slm의 것이 실제로 더 좋습니다. 둘째, 당신은 받아들이지 않는다고 사과해서는 안됩니다. 단 하나만있을 수 있으며 그것이 가장 고려되는 것이어야합니다 :).
terdon

6

허용 대답은 그것이 새로운 급부상 때문에 제대로 작동하지만 다소 비효율적이며 basename각 하위 디렉토리에 대한 프로세스를 :

find /usr/share/festival/lib/voices -maxdepth 2 -mindepth 2 \
    -type d -exec basename {} \;

가능하면 find생성 프로세스 비용을 피하기 위해 내장 된 기능을 사용하는 것이 좋습니다 . 작업을 find사용하여 인쇄 출력을 수정하는 상당히 광범위한 기능이 -printf있습니다. 기본 -print 동작은 전체 경로를 인쇄하지만 -printf및 형식 문자열을 사용하여 인쇄 할 경로 부분을 선택할 수 있습니다. 선행 디렉토리없이 경로의 파일 이름 부분 만 추출하려면 basename 형식 문자열은 %f입니다. 각 파일 이름 뒤에 줄 바꿈을하려면 \n다음을 포함하십시오 .

$ find /usr/share/festival/lib/voices -maxdepth 2 -mindepth 2 \
    -type d -printf '%f\n'
nitech_us_awb_arctic_hts
nitech_us_bdl_arctic_hts
nitech_us_slt_arctic_hts
nitech_us_jmk_arctic_hts
nitech_us_clb_arctic_hts
nitech_us_rms_arctic_hts
ked_diphone
kal_diphone

+1 답변 해 주셔서 감사합니다. Michael. 귀하의 답변 에서이 작업을 수행하는 방법의 이점을 볼 수도 있지만 slm의 답변에 넣은 작업을 감안할 때 허용되는 답변을 전환하는 것에 대해 두 가지 생각을하고 있습니다. @slm이 이것을 보았고 이것을 선택하는 데 아무런 문제가 없다면 여기로 돌아와서 대답을 바꾸겠습니다.
user66001

1
@slm의 대답은 잘 설명되어 find있으며 임의의 외부 명령과 함께 사용하는보다 일반적인 패턴을 다룹니다 . 내장 된 작업에는 효율성이 떨어집니다 find. 나는 그의 답변에 의견을 추가하는 것을 고려했지만, 그것은 나보다 더 명성이 필요합니다. 현재 승인 된 답변이 정확하고 잘 설명되어 있으며보다 일반적인 경우의 패턴으로 사용할 수 있으므로 승인 된 답변을 변경할 필요가 없습니다. 나는이 특별한 경우보다 효율적인 방법이 있음을 지적하고 싶었습니다.
Michael Henry

0

TLDR; 이 질문 의 제목 에 따라 여기에 오는 사람들을 위해 ; "n 레벨 수준의 서브 디렉토리 만 나열": 사용

find -maxdepth N

N숫자는 어디에 있습니까 ?

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.