이 정규식이 grep에서 작동하지 않는 이유를 누군가 설명할 수 있습니까?
ls -la ./ | grep -E '^d.*\<\..*\>$'
내가 보기에는 다음과 같은 이유로 이름이 "."으로 시작하는 디렉토리 행이 표시되어야 하는 것 같습니다.
- ^d -> 문자 "d"로 시작하는 줄 유지
- .* -> 없음 또는 임의의 문자 조합
- $ -> 줄 끝
문제는 내가 이것을 이해하지 못한다는 것입니다.
- \< -> 단어의 시작
- . -> 탈출 지점
- .* -> 없음 또는 임의의 문자 조합
- > -> 단어 끝
그래서 정규식의 이 부분은 점으로 시작하고 문자 조합으로 끝나는 단어가 포함된 줄을 유지한다고 생각합니다.
grep을 사용한 정규식은 이 "ls -la"를 사용하면 결과를 표시하지 않습니다.
[arch dirtest]$ ls -la
total 52
drwxr-xr-x 6 siv users 4096 10 nov 00.41 .
drwx------ 59 siv users 4096 9 nov 23.15 ..
drwxr-xr-x 2 siv users 4096 10 nov 00.41 .test
drwxr-xr-x 2 siv users 4096 10 nov 00.41 test1
drwxr-xr-x 2 siv users 4096 10 nov 00.41 test2
답변1
.
귀하의 정규식 은 단어 문자가 아니기 때문에 작동하지 않습니다 . Grep은 , 및 a-z
만 A-Z
단어 문자로 처리합니다.0-9
_
어쨌든, 이것은 정말로 옳은 일이 아닙니다. 먼저 파싱 ls
은매우 깨지기 쉬운그것은 거의 좋은 생각이 아닙니다. 이름이 다음으로 시작하는 디렉토리를 나열하는 다른 방법은 다음과 같습니다 .
.
find . -type d -name '.*'
또는 하위 디렉터리로 이동하지 않으려는 경우(그리고 GNU가 있는 경우 find
이것이 Linux의 기본값입니다):
find . -maxdepth 1 -type d -name '.*'
또는 echo
Shell glob을 사용할 수도 있습니다.
echo .*
파일도 표시됩니다. 이를 방지하려면 다음과 같은 루프를 사용하세요.
for i in .*; do [ -d "$i" ] && printf '%s\n' "$i"; done
답변2
그 후에 장치 방법을 생략하는 것 같습니까 -D
?
ls -la ./ | grep -D skip '^d.*\<\..*\>$'
\<
어쨌든... 문제는 단어 초기 경계 와 문자 그대로의 지점 을 찾고 있다는 것입니다 \.
. 점은 단어 문자로 간주되지 않기 때문에 항상 실패합니다. info grep
GNU grep에서 인용 :
`-w'
`--word-regexp'
... Word-constituent characters are letters, digits, and the underscore.
\<
공백으로 바꾸는 것이 안정적으로 작동하는 것 같습니다. 그러나 나는 출력을 구문 분석하는 것이 ls -la
불안정하며 원하는 것을 얻는 더 좋은 방법이 있다는 user:terdon의 의견에 동의합니다.