lect1.txt
, lect2.doc
및 이라는 파일이 있습니다 lect3.doc
.
.txt
나는 파일이고 파일 이름을 포함하는 파일을 얻고 싶습니다 lect
.
나는 노력했다
find *.txt | grep lect*
아무것도 반환하지 않습니다.
하지만 내가 할 때
find *.txt | grep "lect*"
돌아왔다 lect1.txt
.
이 두 표현의 차이점은 무엇인가요?
답변1
grep
첫 번째 인수(패턴)에 대해 명령줄에 전달된 파일 검색또는 stdin
파일이 통과되지 않는 경우.
따옴표가 없으면 쉘은 lect*
다음과 같은 디렉토리로 확장됩니다 lect
.
grep lect1.txt lect2.doc lect3.doc
의미는lect1.txt
.doc
두 파일에서 텍스트 검색. 파일 중 하나에 해당 문구가 포함되어 있지 않으면 .doc
아무것도 반환하지 않습니다 . 보다 정확하게는 ( ) 다음 에 가 오는 모든 문자를 lect1.txt
찾으 므로 등도 찾습니다 .)lect1
.
txt
lect1-txt
lect1xtxt
"lect.*"
두 번째 예에서는 셸이 확장하지 않고 그대로 전달하도록 따옴표를 넣습니다 grep
. 패턴을 인수로 전달하기만 하면 grep
전달된 파일 이름 stdin
에서 패턴을 검색할 수 있습니다. .
답변2
find *.txt | grep lect*
find(1)
일반적으로 파일 이름이 아닌 경로 이름을 첫 번째 인수로 제공하려고 합니다 . 확실히 파일 이름 패턴은 아닙니다. 쉘은 *.txt
호출하기 전에 현재 디렉토리에 있는 모든 파일의 이름으로 확장하는데 이는 원하는 바가 아닙니다.*.txt
find
이 명령의 보다 유용한 변형은 다음과 같습니다.
find . -name 'lect*' | grep 'txt$'
또는
find . -name 'lect*txt'
find(1)
또한, 이용에 주의하시기 바랍니다.전역 표현사용하는 -name
동안 기본적 으로grep(1)
일반적인 표현. 이는 *
두 시스템에서 서로 다른 의미를 갖기 때문에 여기서 중요합니다.
BSD 및 GNU 구현에는 정규식을 사용할 수 있는 find
비표준 기본 구현이 있습니다 .-regex
find . -regex '.*/lect.*txt'
이 패턴은 다음과 함께 사용해야 합니다.모두경로를 찾았으므로 find
접두사가 필요하며 를 .*/
사용하는 것처럼 끝까지 고정할 필요가 없습니다 txt
.$
grep
답변3
당신은 그것을 오용했고 find
실수로 작동했습니다. 다음을 실행하면 다음을 볼 수 있습니다.
find *.txt
너 뭐야실제로수행중인 작업은 다음과 같습니다.
find lect1.txt
그리고 당신이 성취한 것은 echo
. 그러나 검색 기준을 사용하여 find를 실행하는 경우(예:
find . -name '*.txt'
그런 다음 현재 디렉터리를 반복 .
하고 사양과 일치하는 하위 디렉터리의 파일 이름을 인쇄합니다.
*
하지만 '*'는 find, 셸 및 *
정규식 에서 다르게 해석되므로 주의해야 합니다 .
grep
귀하의 ing이 *
"이전 문자의 0개 이상의 인스턴스"를 의미하는 경우 .
그래서 당신은 실제로:
- 모든 파일 이름을 에코합니다(globbing
*.txt
). lec
grepping은 중간에 , 등이lect
있는lectt
문자 와 일치하는 모든 항목을 인쇄합니다.lecttttttt
하지만 첫 번째 예에서는 grep이 그렇게 멀리까지 가지도 않습니다.껍데기패턴을 확장하여 실제로 일치하는 항목을 찾고 있습니다. echo lect*
디렉터리에 적절하게 확장되는 파일이 있지만 원하는 작업을 수행하지 않기 때문에 예기치 않게 작동할 수 있습니다.
나는 당신이 원하는 것을 제안합니다 :
find . -name 'lect*.txt' -print