새로운 10년: "find /path/ -name 'file.20{19,20}*"과 같은 말을 하는 방법(그러나 작동함)

새로운 10년: "find /path/ -name 'file.20{19,20}*"과 같은 말을 하는 방법(그러나 작동함)

요약:

  1. 특정 시스템에는 이름이 포함된 많은 텍스트 파일이 있습니다 ~= [type of file].[8-digit date].
  2. 이러한 파일을 검색하려면 다음 관용어를 사용하는 것이 좋습니다(그리고 유지하고 싶습니다). ( find /path/ -name 'file.nnnn*' -print | xargs -e fgrep -nH -e 'text I seek'여기서 nnnn== 연도는 4자리)
  3. ...지난 10년 동안 저는 find수년에 걸쳐 글로벌 협업도 수행했습니다.find /path/ -name 'file.201[89]*' -print | xargs ...
  4. find...하지만 이제 2019년과 2020년에는 사용할 수 없습니다 .find /path/ -name 'file.20{19,20}*' -print | xargs ...
  5. ..."중괄호 와일드카드"(정확한 용어?)는 잘 작동할 수 있지만 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}*

그러므로 나는 알고 싶습니다:

  1. find이 사용 사례에 대해 올바른 glob을 제공 하지 않는 걸까요 ? 그것이 할 수 있는/올바른 일을 find하기 위해 무엇을 말해야 합니까 ?ls
  2. 이것이 문제입니까 xargs? 그렇다면 find ... -exec해결책을 받아들일 수 있지만... 내 두뇌는 와 같은 상황에서 더 잘 작동하므로 xargs가능하면 그것을 고수하는 것이 좋습니다. (제가 정신지체자라고 할 수 있지만 -exec문법이뇌를 아프게 해.)

답변1

를 사용하면 십진수 범위와 일치하는 zsh재귀 와일드카드 및 해당 와일드카드 연산자를 사용할 수 있습니다 .<x-y>

grep -nHFe 'text I seek' /path/**/file.<2019-2020>*(D-.)

( 숨겨진( ot) 디렉토리 (D)도 볼 수 있습니다 . 원하지 않으면 아마도 생략하고 다음으로 제한할 수 있습니다.Dfind-.정기적인파일( .)은 심볼릭 링크 해석( ) 후에 식별됩니다 -.

이는 on file.00002020(2019에서 2020 사이의 십진수이므로)과도 일치하며, on 메서드와 마찬가지로 which match 와 일치 file.20201234합니다 .file.2020file.<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/nullGNU의 파일 이름 강제 표시와 동일합니다.)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}파일 foo1foo2.

중괄호 확장을 사용하여 디렉터리를 재귀적으로 검색하려면 bash에서 재귀적 글로빙을 활성화할 수 있습니다(globstar) (아마도 dotglob이와 같은 숨겨진 디렉토리를 볼 수 있음 find) printf다음과 함께 사용하십시오 xargs.

shopt -s globstar
printf "%s\0" /path/**/file.20{19,20}* | xargs -0 ...

또는 일부 구현 에서 지원하는 대신 findwith를 사용할 수도 있습니다 . GNU 사용 :-regex-namefindfind

find  /path -regextype posix-extended -regex '.*/file.20(19|20)[^/]*'

답변3

이는 귀하의 질문에 대한 일반적인 답변은 아니지만, 보유하고 있는 파일 기록의 양에 따라 쉬운 방법이 있을 수 있습니다. 나는 9월이나 10월에 물건을 찾을 때 비슷한 상황에 자주 직면합니다. 간단한 해결 방법은 다음과 같은 패턴을 사용하는 것입니다.

file.20[12][90]*

2019년과 2020년 외에 2010년과 2029년도 일치하기 때문에 동일하지 않습니다. 아마도 2029년 날짜의 문서가 아직 없을 것 같습니다. 아카이브가 2010년으로 돌아가지 않으면 기능적으로 동일해야 합니다.

관련 정보