디렉터리 계층 구조에서 파일에 대해 악센트를 구분하지 않고 검색을 수행하고 싶습니다.
$ touch a ą ä à á â
$ find . -iname '*a*'
./a
# How do I get find to return all 6 filenames?
저는 데비안 11, Bullseye를 실행하고 있습니다.
내 거교정자매우 약한!
악센트를 구분하지 않는 방식으로 조회가 작동하도록 할 수 있는 옵션, 로케일 또는 다른 방법이 있습니까?
의견에서 요청한 대로 locale
다음을 반환합니다.
LANG=en_GB.UTF-8
LANGUAGE=en_GB:en
LC_CTYPE="en_GB.UTF-8"
LC_NUMERIC="en_GB.UTF-8"
LC_TIME="en_GB.UTF-8"
LC_COLLATE="en_GB.UTF-8"
LC_MONETARY="en_GB.UTF-8"
LC_MESSAGES="en_GB.UTF-8"
LC_PAPER="en_GB.UTF-8"
LC_NAME="en_GB.UTF-8"
LC_ADDRESS="en_GB.UTF-8"
LC_TELEPHONE="en_GB.UTF-8"
LC_MEASUREMENT="en_GB.UTF-8"
LC_IDENTIFICATION="en_GB.UTF-8"
LC_ALL=
답변1
TL;DR 끝까지 스크롤
이것은 좋은 질문입니다. 질문해주셔서 감사합니다.
내가 아는 한, 악센트를 구분하지 않는 검색을 수행하는 것이 가능하지만 기본적으로는 아니고 자동으로 수행되는 것도 아닙니다. 다음 명령을 사용하여 6개의 샘플 파일을 모두 찾을 수 있습니다.
find . -name '[[=a=]]'
이는 유사하지만 악센트가 있는 모든 문자를 나타내는 데 사용되는 표준 POSIX glob 표기법입니다.
따라서 악센트 버전이 있을 수 있는 모든 문자를 알고 있는 경우 위 표기법을 사용할 수 있습니다.분명히귀하의 검색에서. 예를 들어:
find . -name 'fran[[=c=]]ais' # To match a cedilla
그러나 그것은 지루하고 매우 불만족스럽습니다.
이 [[=a=]]
표기법은 악센트 버전이 없는 문자에도 사용할 수 있습니다. 그래서 [[=k=]]
일치합니다 k
.
그래서 저는 스크립트를 만드는 것을 제안합니다(악센트가 있는)는 명령줄에서 문자열을 가져와 [[=x=]]
각 문자를 해당 버전으로 바꾸고 결과를 인쇄한 다음 다음과 결합할 수 있습니다.찾다. 예를 들어:
#!/usr/bin/env perl
print join('', map { /\p{Letter}/ ? "[[=$_=]]" : $_ } split //, $ARGV[0]), "\n";
함께 사용하세요찾다다음과 같이 보일 수 있습니다:
find . -name "`accented a`"
자동으로 느껴지기를 원하고 그냥 사용한다면찾다가장 간단한 방법으로 쉘 스크립트(파인더)결합찾다그리고악센트가 있는:
#!/bin/sh
find "$1" -name "`accented \"$2\"`"
그러면 다음과 같이 할 수 있습니다:
ffind . a
하지만 이렇게 하면 사용할 수 없게 됩니다.찾다다른 술어.
필요할 땐 실물을 이용해야지찾다그리고악센트가 있는명시적으로(위와 같이).
여기
더 똑똑한 솔루션은 래퍼입니다찾다(파인더) -name
및 -iname
매개변수를 스캔하여 효과적으로 적용합니다.악센트가 있는다음 매개변수에 추가한 후 수정된 결과를 실행합니다.찾다주문하다. 예를 들어:
#!/usr/bin/env perl
use warnings;
use strict;
# ffind - find wrapper that makes -name and -iname accent-insensitive
my @cmd;
while (@ARGV)
{
# Gather command line arguments
push @cmd, shift @ARGV;
# Make -name and -iname arguments accent-insensitive
if ($cmd[-1] =~ /^-i?name$/ && @ARGV)
{
push @cmd, join('', map { /\p{Letter}/ ? "[[=$_=]]" : $_ } split //, shift @ARGV);
}
}
exec 'find', @cmd;
그런 다음 이 작업을 수행하여 6개의 예제 파일을 모두 찾을 수 있습니다.
ffind . -name a
물론 전화도 가능해요찾다'find'
마지막 줄을 로 변경하면 '/usr/bin/find'
이렇게 됩니다.찾다투명하게 악센트를 구분하지 않음:
find . -name a
불행히도 이 전체 방법은 Debian 12와 같은 일부 시스템에서만 작동하지만 전부는 아닙니다. :-(
답변2
이름을 분해된 형식으로 변환하고 결합 표시를 제거한 후 다음을 확인할 수 있습니다.
find . -print0 |
perl -C -MUnicode::Normalize -MFile::Basename -0 -lne '
$name = NFD(basename($_)) =~ s/\pM//r;
print if $name =~ /a/' |
xargs -r0 ls -ld --