요약:
- 특정 시스템에는 이름이 포함된 많은 텍스트 파일이 있습니다
~=
[type of file].[8-digit date]
. - 이러한 파일을 검색하려면 다음 관용어를 사용하는 것이 좋습니다(그리고 유지하고 싶습니다). (
find /path/ -name 'file.nnnn*' -print | xargs -e fgrep -nH -e 'text I seek'
여기서nnnn
== 연도는 4자리) - ...지난 10년 동안 저는
find
수년에 걸쳐 글로벌 협업도 수행했습니다.find /path/ -name 'file.201[89]*' -print | xargs ...
find
...하지만 이제 2019년과 2020년에는 사용할 수 없습니다 .find /path/ -name 'file.20{19,20}*' -print | xargs ...
- ..."중괄호 와일드카드"(정확한 용어?)는 잘 작동할 수 있지만
ls
!
find
사후 정리 없이 내가 원하는 것이 무엇인지 find
(예: 내가 지금 하고 있는 것) 알려주는 {간결하고 우아한} 방법이 있나요?
find /path/ -name 'file.*' -print | grep -e '\.2019\|\.2020' | xargs ...
? FWIW, 나는 xargs
.
세부 사항:
제가 작업하는 시스템에는 저 이전부터 존재해 왔고 변경할 수 없는 많은 관습이 있습니다. 그 중 하나는 ~=
[type of file].[8-digit date]
예를 들어 이라는 이름의 텍스트 파일이 많이 있다는 것입니다 . 나는 일반적으로 woohoo_log.20191230
이 파일에서 특정 텍스트를 검색할 때 관용어 find ... grep
(보통 Emacs' 사용 M-x find-grep
)를 사용합니다. (FWIW, 이것은 Linux 시스템입니다.
$ find --version
find (GNU findutils) 4.4.2
...
$ bash --version
GNU bash, version 4.3.30(1)-release (x86_64-pc-linux-gnu)
현재는 원하는 경우 변경할 수 있는 상태가 없습니다. ) 나는 종종 현재 작업의 연도 범위를 알고 있으므로 find
(작업 속도를 높이기 위해) 반환되는 항목을 제한하려고 노력할 것입니다.
find /path/ -type f -name 'file.nnnn*' -print | xargs -e fgrep -nH -e 'text I seek'
여기서 nnnn
== 4자리 연도입니다. 제가 좋아하는(그리고 유지하고 싶은) 이 WFM은 위의 관용구를 사용합니다. 특히 수년간 검색하는 데에도 사용할 수 있기 때문입니다.
find /path/ -type f -name 'file.201[89]*' -print | xargs ...
하지만 새로운 10년이 지나면서 그런 습관이 깨지고 있는 것 같고, (적어도 나에게는) 가장 이상한 점은 바로 이것이다. (지난 10년 동안 상황이 바뀌었을 때 나는 여기에 없었습니다.) 내가 원하는 텍스트를 선택한다고 가정해 보겠습니다.알다2019년 파일 && 2020년 파일에 위치합니다(즉, 파일을 열고 텍스트를 볼 수 있습니다). 내가 지금 이걸 하면
find /path/ -name 'file.20{19,20}*' -print | xargs ...
grep
예상치 못한/짜증나는 일을 한 with no matches found
이유는 다음과 같습니다.
$ find /path/ -name 'file.20{19,20}*' -print | wc -l
0
하지만 내가 그렇게 한다면
find /path/ -type f -name 'file.*' -print | grep -e '\.2019\|\.2020' | xargs ...
grep
예상된 결과를 반환합니다. 좋은데... 음... 특히 이 "중괄호 글로브" 때문에 보기 흉합니다(이 사용법이 올바르지 않거나 더 이상 사용되지 않는 경우 수정해 주세요) 작동 방식 ls
! 즉, 관련 연도 범위(예: 2019..2020) 내의 문서를 표시합니다.
ls -al /path/file.20{19,20}*
그러므로 나는 알고 싶습니다:
find
이 사용 사례에 대해 올바른 glob을 제공 하지 않는 걸까요 ? 그것이 할 수 있는/올바른 일을find
하기 위해 무엇을 말해야 합니까 ?ls
- 이것이 문제입니까
xargs
? 그렇다면find ... -exec
해결책을 받아들일 수 있지만... 내 두뇌는 와 같은 상황에서 더 잘 작동하므로xargs
가능하면 그것을 고수하는 것이 좋습니다. (제가 정신지체자라고 할 수 있지만-exec
문법이뇌를 아프게 해.)
답변1
를 사용하면 십진수 범위와 일치하는 zsh
재귀 와일드카드 및 해당 와일드카드 연산자를 사용할 수 있습니다 .<x-y>
grep -nHFe 'text I seek' /path/**/file.<2019-2020>*(D-.)
( 숨겨진( ot) 디렉토리 (D)
도 볼 수 있습니다 . 원하지 않으면 아마도 생략하고 다음으로 제한할 수 있습니다.D
find
-.
정기적인파일( .
)은 심볼릭 링크 해석( ) 후에 식별됩니다 -
.
이는 on file.00002020
(2019에서 2020 사이의 십진수이므로)과도 일치하며, on 메서드와 마찬가지로 which match 와 일치 file.20201234
합니다 .file.2020
file.<2019-2020>
1234
*
표준(POSIX sh
및 유틸리티) 접근 방식은 다음과 같습니다.
find /path \( -name 'file.2019*' -o -name 'file.2020*' \) -type f \
-exec grep -Fne 'text I seek' /dev/null {} +
(추가된 효과는 /dev/null
GNU의 파일 이름 강제 표시와 동일합니다.)grep
-H
의 출력은 find -print
의 예상 입력 형식과 호환되지 않습니다 xargs
. GNU 유틸리티를 사용하면 find -print0
및 를 사용할 수 있지만 동작이 동일하고 더 짧고 이식성이 높기 xargs -r0
때문에 필수는 아닙니다 .find -exec ... {} +
답변2
에서는 와 아무 관련이 ls -al /path/file.20{19,20}*
없습니다 . 이 명령에서 쉘은 다음을 실행합니다.ls
{19,20}*
버팀대 확장그리고와일드카드/path/file.20{19,20}*
~처럼참조되지 않습니다:
bash-5.0$ set -x
bash-5.0$ echo {a,b}
+ echo a b
a b
bash-5.0$ ls {a,b}
+ ls a b
ls: cannot access 'a': No such file or directory
ls: cannot access 'b': No such file or directory
bash-5.0$ find -iname {a,b}
+ find -iname a b
find: paths must precede expression: `b'
는 에 인용되어 find /path/ -name 'file.20{19,20}*'
있으므로 'file.20{19,20}*'
쉘은 이를 무시하고 find
자체 적용합니다.패턴 일치 규칙, 중괄호 확장을 지원하지 않습니다. 여기에 인용됨GNU find
매뉴얼:
패턴(' ')
{}
내의 중괄호는 특수한 것으로 처리되지 않습니다(find . -name 'foo{1,2}'
예 :foo{1,2}
파일foo1
및foo2
.
중괄호 확장을 사용하여 디렉터리를 재귀적으로 검색하려면 bash에서 재귀적 글로빙을 활성화할 수 있습니다(globstar
) (아마도 dotglob
이와 같은 숨겨진 디렉토리를 볼 수 있음 find
) printf
다음과 함께 사용하십시오 xargs
.
shopt -s globstar
printf "%s\0" /path/**/file.20{19,20}* | xargs -0 ...
또는 일부 구현 에서 지원하는 대신 find
with를 사용할 수도 있습니다 . GNU 사용 :-regex
-name
find
find
find /path -regextype posix-extended -regex '.*/file.20(19|20)[^/]*'
답변3
이는 귀하의 질문에 대한 일반적인 답변은 아니지만, 보유하고 있는 파일 기록의 양에 따라 쉬운 방법이 있을 수 있습니다. 나는 9월이나 10월에 물건을 찾을 때 비슷한 상황에 자주 직면합니다. 간단한 해결 방법은 다음과 같은 패턴을 사용하는 것입니다.
file.20[12][90]*
2019년과 2020년 외에 2010년과 2029년도 일치하기 때문에 동일하지 않습니다. 아마도 2029년 날짜의 문서가 아직 없을 것 같습니다. 아카이브가 2010년으로 돌아가지 않으면 기능적으로 동일해야 합니다.