질문 - -grep을 사용하여 디렉토리의 파일 나열

질문 - -grep을 사용하여 디렉토리의 파일 나열

질문에서는 /usr/bin파일 이름에 영어 소문자만 포함되고 "file"이라는 단어가 포함된 저장된 모든 파일을 나열하고 싶습니다.

예를 들어, 출력에 nsrfileand 가 있어야 합니다.file

이것을 달성하기 위한 내 코드는 다음과 같습니다.

ls /usr/bin | grep '\<[a-z]*file[a-z]*\>'

내가 얻은 결과 중 일부는 다음과 같습니다.

file
nsrfile
grub2-file
systemd-tmpfiles

그런데 파일 이름에는 슬래시가 아닌 영문 소문자만 포함할 수 있다는 질문이 있습니다.-

grub2-file심지어 숫자 도 포함되어 있습니다

명령을 어떻게 변경해야 합니까?

답변1

기대와 경고

작업에서 얻을 수 있는 grep결과 ls는 아마도 다음과 같습니다.

cd /usr/bin
ls | grep '^[a-z]*$' | xargs grep file

ls파일 이름을 요청할 때 grep소문자로만 시작( )하고 끝나는( ) 필터를 사용합니다. 그런 다음 들어오는 각 파일 이름을 grep하여 문자열 "file"을 찾도록 요청합니다.^$*xargs

파일 이름(/usr/bin에 없을 가능성이 높음)에 개행 문자가 포함되면 즉시 문제가 발생합니다. (공백이 있는 파일은 Some File Namegrep에 의해 제외됩니다.) 이 점을 인위적인 예를 통해 설명하려면 다음을 수행하십시오.

cd ~/tmp/usr/bin
touch a$'\n'b
ls | grep '^[a-z]*$' | xargs grep file
grep: a: No such file or directory
grep: b: No such file or directory

위의 예에서는 lsgrep의 파이프에 다음이 기록됩니다.

a
b

Grep은 이 두 "파일 이름"을 xargs로 올바르게 파이프한 다음 xargs는 grep에 대한 두 개의 파일 이름이 있다고 생각하여 실행됩니다.

grep file a b

...그리고 파일 누락에 대해 불평합니다.

제안

이는 예상되지 않지만 다음과 같은 보다 안전한 옵션을 사용하는 것이 좋습니다(bash 쉘 가정).

shopt -s extglob
grep -l file /usr/bin/!(*[^a-z]*)

이것이 열릴 것이다Bash용 확장 와일드카드기능. 그런 다음 "file"이라는 문자열이 포함된 파일 이름을 /usr/bin( )의 파일에 grep나열하도록 요청합니다.-l아니요( !)는 다음 패턴과 일치합니다. "모든 항목 ( *) 뒤에 임의의 단일 ( [ ... ]) 비( ^) 소문자 ( a-z), 그 뒤에 아무 항목 ( *)이 옵니다. 즉, 다음을 포함하는 파일만오직이름에 소문자.

답변2

나는 무엇을 할 것인가:

printf '%s\n' /usr/bin/* |
    grep '\<[a-z]*file[a-z]*\>' | grep -Ev '[0-9]|-'

설명하다:

 grep -v

역 grep입니다. 두 가지 모드가 있습니다 [0-9]:-

답변3

두 가지 솔루션:

쉘 루프:

for name in /usr/bin/*file*; do
   case "${name##*/}" in
        *[!a-z]*) ;;
        *) printf '%s\n' "$name"
   esac
done

/usr/bin먼저 기본 이름이 일치하는 경로 이름 목록을 생성한 *file*다음 해당 기본 이름에 소문자 이외의 문자도 포함되어 있는지 테스트합니다. 소문자 이외의 문자가 발견되지 않으면 경로 이름이 인쇄됩니다.

기준에 맞는 디렉터리 이름을 찾을 수도 있습니다. 네가 원하는 게 그게 아니라면 이렇게 해라

[ ! -f "$name" ] && continue

문 앞에 있는 case각 비정규 파일의 이름을 건너뜁니다 .

GNU 사용 find:

find /usr/bin -maxdepth 1 -type f -name '*file*' -regex '.*/[a-z]*$'

이 역시 두 가지 수준의 필터링을 거칩니다. 먼저 일치해야 하는 기본 이름에 *file*, 그런 다음 경로 이름 끝에( -regex전체 경로 이름과 일치) 소문자만 있는지 확인하십시오.

답변4

ls /usr/bin | grep '\<[a-z][^\-]*file[a-z][^\-]*\>'

관련 정보