십만 개 이상의 ID가 포함된 파일이 있습니다. 각 ID는 8~16개의 16진수 숫자로 구성됩니다.
178540899f7b40a3
6c56068d
8c45235e9c
8440809982cc
6cb8fef5e5
7aefb0a014a448f
8c47b72e1f824b
ca4e88bec
...
포함 항목을 둘러싼 디렉터리 트리에서 관련 파일을 찾아야 합니다.2×10 9문서.
와 같은 ID가 주어지면 다음을 6c56068d219144dd
통해 해당 파일을 찾을 수 있습니다.
find /dir -type f -name '* 6[cC]56068[dD]219144[dD][dD] *'
하지만 이 작업을 완료하는 데는 최소 이틀이 소요됩니다.
내가 원하는 것은 가능한 find
한 많은 -o -iname GLOB
세쌍둥이를 호출하는 것입니다 ARG_MAX
.
내가 하고 싶은 일은 다음과 같습니다.
sed -e 's/.*/-o -iname "* & *"' ids.txt |
xargs find /dir -type f -name .
내 문제는 온전한 세 쌍둥이만 받아들이도록 강요할 수 없다는 것입니다 xargs
.
어떻게 해야 합니까?
답변1
이것은 잘못된 접근 방식입니다. 이름이 공백으로 구분된 단어 중 하나로 이러한 ID 중 하나를 갖는 모든 파일을 찾는 것이 목적이라면 다음과 같이 할 수 있습니다.
find /dir -type f -print0 |
gawk '
!ids_processed {ids[$0]; next}
{
n = split(tolower($NF), words, " ")
for (i = 1; i <= n; i++)
if (words[i] in ids) {
print
break
}
}' ids.txt ids_processed=1 RS='\0' FS=/ -
그런 다음 파일 목록을 한 번만 처리하고 100,000개의 ID를 찾는 것은 최대 100,000개의 정규식/와일드카드 일치를 수행하는 대신 해시 테이블을 찾는 것입니다.
답변2
나는 무엇을 할 것인가:
모든 파일 이름을 임시 파일에 저장하는 스크립트를 작성하십시오.
# maybe run this from cron or behind inotifywait
find dir -type f -print > /tmp/filelist
그런 다음 입력 파일을 사용하여 필요에 따라 조회를 수행합니다.
fgrep -if hexids /tmp/filelist
-wif
대신 사용을 제안할 수도 있지만 -if
다른 의견을 보면 귀하의 질문에 정확한 정보를 제공했는지 확실하지 않습니다. man grep
더 많은 정보를 알고 싶습니다.
답변3
@Kusalananda 덕분에 가능한 해결책을 생각했습니다.
첫 번째 단계는 각 -a -b X
세 쌍을 단일 인수로 처리하도록 만드는 것입니다 xargs
. 그런 다음 인라인 스크립트에서 이러한 단일 인수 트리플을 다시 분할 sh
하고 그 안에서 유틸리티를 호출합니다.
... |
awk '{ printf("%s%c", $0, 0) }' |
xargs -0 sh -c '[ "$#" -gt 0 ] && { printf %s\\n "$@" | xargs "$0" }' my_command