디렉토리없이 파일을 나열하고 이름으로 필터링하는 방법 (ls 옵션)


42

라는 디렉토리가 uploads있습니다. 여기에는 많은 파일과 파일을 포함하는 몇 개의 서브 디렉토리가 포함됩니다.

한 단계로 다음을 수행 할 수있는 방법이 있습니까?

  1. 루트 업로드 디렉토리에있는 파일 만 나열하십시오. 하위 폴더 이름이나 내용을보고 싶지 않습니다.

  2. 로 시작하는 파일을 나열하지 마십시오 t_

나는 -d깃발 에 대해 알고 있지만, 내가 원하는 것을 얻지 못한다.

답변:


53

의 직업인 것 같습니다 find.

  • -maxdepth하위 폴더 내에서 반복적으로 검색하지 않고 현재 디렉토리 만 반환하는 데 사용
  • -type f디렉토리 나 장치 노드 등을 제외한 파일 만 반환하는 데 사용
  • 경우에 조합을 사용 -not하고 -name원하지 않는 이름을 가진 파일을 피하기 위해

다음과 같이 함께 나타날 수 있습니다.

find /path/to/uploads -maxdepth 1 -type f -not -name 't_*'

감사! 저는 CLI를 처음 접했고 이전에 find를 사용한 적이 없었습니다. 나는 그것에 대해 더 자세히 살펴볼 것이다.
EmmyS

2
@EmmyS : 여기서 약간의 유용한 정보를 찾을 수 있습니다. @Gilles는 -exec ls -lG -- {} +추가 옵션을 사용하여 ls에 출력을 얻기 위해 그의 대답에 사용 하는 것을 언급 했습니다. -lsls의 상세도에 대한 빠르고 더러운 근사값을 얻기 위해이 결과에 그냥를 추가 할 수도 있습니다 .
Caleb

18

GNU ls (즉, 내장되지 않은 Linux 시스템의 ls 명령 및 다른 유니스에서도 사용 가능한 Cygwin)에는 이름을 기준으로 일부 파일을 숨기는 옵션이 있습니다. 디렉토리를 무시할 방법이 없습니다.

ls --hide='t_*' uploads

또 다른 방법은 쉘이 일치하도록하는 것입니다. Bash, ksh 및 zsh에는 !(t_*)일치하는 파일을 제외한 모든 파일을 일치 시키는 부정 패턴 이 있습니다 t*. bash에서는이 기능을 사용하여 설정해야 shopt -s extglob하며 zsh에서는을 사용하여 설정해야합니다 setopt ksh_glob. Zsh에는 또한 ^t_*으로 설정해야하는 동등한 구문 이 있습니다 setopt extended_glob. 이것은 여전히 ​​디렉토리를 무시하지 않습니다. Zsh에는 이름뿐만 아니라 메타 데이터 등으로도 파일을 일치시킬 수있는 추가 기능이 있습니다. glob 한정자 . (.)일치하는 끝에 추가 하여 일반 파일로 제한하십시오. 부정 ^은 이름 일치 구문의 일부이므로 ^t_*(.)"정규 파일 t_*과 일치 하지 않는 모든 파일"이 아니라 " 일치하지 않는 모든 일반 파일"을 의미 합니다 t_*.

setopt extended_glob  # put this in your ~/.zshrc
ls uploads/^t_*(.)

고급 도구없이 자신을 찾으면으로 모든 유닉스에서이 작업을 수행 할 수 있습니다 find. 일반적으로 명령 줄에 입력하는 것은 아니지만 강력하고 정확합니다. Caleb은 이미 GNU find로이를 수행하는 방법을 보여주었습니다 . -maxdepth옵션을 이식 할 수 없습니다; -prune대신 재귀를 막기 위해 대신 사용할 수 있습니다 find.

find uploads/* -type d -prune -o \! -type f -name 't_*' -print

교체 -print에 의해 -exec ls -lG -- {} +실행하는 ls파일에 당신의 마음에 드는 옵션.

위의 모든 명령은 도트 파일 (즉, 이름이로 시작하는 파일)을 숨 깁니다 .. 당신이 그들을 표시 통과 할 경우 -Als, 또는 추가 Dzsh을에 글로브 한정자를 ( ls uploads/^t_*(.D)). 을 사용하면 find한 수준 만 반복하도록 다른 접근 방식을 사용할 수 있습니다 ( find점 파일은 특별히 처리하지 않음). find현재 디렉토리에서 실행 하는 경우에만 완벽하게 작동합니다 .

cd uploads && find . -name . -o -type d -prune -o \! -type f -name 't_*' -print

3
주무세요? ;-) Unix SE에서 가장 간단한 질문까지 답변의 길이와 수준에 지속적으로 놀랐습니다! .. 어쨌든 계속하십시오! :)
alex

감사! 훌륭한 세부 사항. 지금 "고급 도구"가 있는지 모르겠습니다. 저는 직장에서 Mac을 사용하고 있습니다 (집에서 Linux를 사용하더라도 어느 시점에서 유용 할 것입니다.)
EmmyS

@EmmyS : 리눅스 박스에서 내가 사용하는 -maxdepth것이 좋지만 Gilles가 언급 한 "휴대 성"문제는 BSD find(OSX에서도 발견됨)가 약간 다른 동물이기 때문에 그의 대답이 필요할지도 모른다. @Gilles : zsh 트릭에 +1!
Caleb

1
@Gilles : 대한 몇 가지 때문에 수분이없는 의견 prune들 마음에 와서,하지만 난 단순히 내 자신의 시스템에 배 생각 "의 수를 주위에 일 처리있을 때하는 것을 말하며 가자거야 내가이 명령 작업에 있었다 것인지 AIX, Solaris 또는 MINIX3 "는 대략 ... 대기입니다 ... 미터 표시 값을 얻는 데 어려움을 겪고 있습니다 ... 디스플레이가으로 고정됩니다 0.00.
Caleb

2
Gnu ls에는 --use-telepathy옵션이 없습니까? 원하는 파일 만 표시하는 가장 빠른 방법입니다. 휴대용이 아닐 수도 있습니다.
dubiousjim

8
ls -l /folder | grep ^- | awk '{print $9}'

$9이 진술에는 무엇이 있습니까?
EmmyS

3
@EmmyS 출력의 9 번째 필드 / 열을 의미합니다. 이 답변은 출력구문 분석ls 하려고합니다 .
jw013

print $ NF`가 더 나아질 것입니다. IMO. $ NF는 9의 필드 수를 의미하며 다른 사람들에게 $ NF에 대해 가르 칠 수있는 좋은 기회로서 AWK에서 일반적으로 사용됩니다.
Elijah Lynn

1
ls -l | grep -v ^d | grep name$

이 솔루션 (여러 명령과 파이프가 필요함)을 선호하는 이유는 무엇입니까 find?
HalosGhost

간결하고 읽기 쉽고 ls 명령 규칙으로 유지됩니다. find 명령 인수보다 기억하기가 더 쉽다는 것을 알았습니다. 옵션에 대한 각각의 자신과 kudos에게!
tkjef

0

ls파이프를 사용하여 샷을 드리겠습니다 .

ls  -l --hide='t_*'  uploads/ | grep -v ^d | tr -s ' ' | cut -d ' ' -f 9

마지막 열은 9 번째 열이라고합니다.


1
공백이있는 파일이 있으면 어떻게됩니까?
jordanm

0

find의 -maxdepth 이식성 문제가 우려되는 경우 다음을 사용할 수 있습니다.

ls -l uploads/ | awk '/^-/ && $9 !~/^t_/ {print $9}'

나는 전문가는 아니지만 이것이 효과가 있다고 생각합니다. 나는 조금 암호처럼 보이지만, 당신이 awk라고 말하면, 실제로는 그렇지 않습니다. $ NF 대신 $ NF를 사용할 수 있습니다. 당신은 또한 할 수 있습니다 :

ls -l uploads/ | awk '/^-/' | awk '!/^t_/ {print $9}'

그것은 같은 일을하지만 (아마도 이전의 것보다 덜 효율적입니다).

실제로 다른 게시물에 대해 생각한 후에는

ls -l --hide=t_* uploads/ | awk '/^-/ {print $9}'

더 짧고 명확한 방법입니다.

내가 틀렸다면 누군가 나를 수정하십시오. :-)


파싱 ls은 일반적으로 좋은 생각이 아닙니다 . 예를 들어 공백이있는 파일 이름으로 어색한 트릭이 실패합니다.
Mat

@mat-수정 해 주셔서 감사합니다. 당신 (및 jw013)이 지적한 기사를 읽은 후 ls 가 올바른 파일 이름을 출력하도록 신뢰할 수 없음을 알았습니다 . $ 9에서 줄 끝까지 (공백 포함) 모든 것을 인쇄하기 위해 awk 코드를 다시 작성 하더라도이 ls 출력은 여전히 ​​잘못된 것일 수 있습니다. 이는 실망스럽고 수정 된 IMO입니다. 다시 감사합니다.
kkaszub 2016 년

0

나는 이러한 짧은 길을 발견했다.

ls -p uploads | grep -Ev '/'

또는

ls -pIt_* uploads | grep -v /

-1

이 별칭을 사용 해보고 사용하십시오.

alias l='ls -hLlF'

ls -hLlF하위 디렉토리를 표시하고로 시작하는 파일을 표시합니다 t_. 그렇다면 이것이 어떻게 질문에 대답합니까?
Raphael Ahrens

아마도 나는 그 질문을 오해했을 것입니다. ls -hLlF는 링크 된 디렉토리의 대상 디렉토리를 표시하지 않습니다.
Granular

그런 것 같아. 그러나 질문에 대한 다른 답변을 읽지 않았습니까?
Raphael Ahrens

-1

쉬워요:

ls -l --hide 't_*' <absolute path to desired directory> | grep -v ^d


(1)이 답변은 매우 쉽습니다. (2) 디렉토리의 전체 경로를 지정해야한다고 생각하는 이유는 무엇입니까?
Scott

@Scott-솔루션을 얻는 매우 빠르고 간단한 방법입니다. 전체 경로는 대답을 보편적으로 만들기 위해 지정되었습니다 ...
Digger
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.