질문에서는 /usr/bin
파일 이름에 영어 소문자만 포함되고 "file"이라는 단어가 포함된 저장된 모든 파일을 나열하고 싶습니다.
예를 들어, 출력에 nsrfile
and 가 있어야 합니다.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 Name
grep에 의해 제외됩니다.) 이 점을 인위적인 예를 통해 설명하려면 다음을 수행하십시오.
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
위의 예에서는 ls
grep의 파이프에 다음이 기록됩니다.
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][^\-]*\>'