인덱스 파일 메타데이터

인덱스 파일 메타데이터

다음을 기반으로 파일을 색인(검색)할 수 있는 도구가 있습니까?메타데이터리눅스에서? 검색해서 찾았습니다(여기) Linux에서 파일 인덱싱을 허용하는 여러 도구가 있습니다.

그러나 이러한 인덱스 파일에는 메타데이터가 없는 것 같습니다(또는 문서에서 방법을 찾지 못했을 수도 있습니다).이것대답처럼 보일 수도 있지만 문서가 짧기 때문에 이것이 실제로 내가 찾고 있는 것인지 알 수 없습니다.

나는 이것을 찾았다:G 작업공간, 이는 매우 합법적이지는 않지만 메타데이터 기반 색인 생성을 허용한다고 명시되어 있습니다.

GWMetadata는 활성 폴더 기능을 포함하는 메타데이터 색인 및 검색 시스템입니다.

내 목표

보다 정확하게는 macO에서 (기본적으로) 수행할 수 있는 작업을 모방하고 싶습니다.

# Create a file and set metadata
touch test_file.txt
xattr -w com.apple.metadata:MY_META todo test_file.txt
# Wait a few seconds for the index to update
sleep 5
# Search files that have a given metadata
mdfind "MY_META=todo"

방금 생성한 파일의 경로를 반환합니다. $(pwd)/test_file.txt.이 몇 가지 명령을 자동화해야 하기 때문에 CLI 인터페이스가 있는 도구를 찾고 있습니다.

답변1

나는 Linux(Debian 버전) 또는 BSD 호스트에 유사한 기능이 있다는 것을 알지 못하지만 xattr활성화된 시스템에서는 직접 구현하기에는 그리 복잡하지 않습니다. 나는 당신에게 가능한 해결책을 제공합니다이 답변 끝에POSIX 호환 스크립트 형식찾다(아닙니다색인그 자체). CLI 사용 도움말 기능을 통합했으므로 사용 단계에 도달하기 위해 코드의 모든 세부 사항을 자세히 살펴볼 필요는 없지만 전체적으로는 "코드 읽기"가 최선의 조언입니다.

인덱스는 수정되지 않은 채로 스크립트를 실행해야 하지만 데몬(아마도 systemd서비스 단위)으로 실행하고 소규모 데이터베이스를 업데이트해야 합니다(일종의 테이블에 관련 데이터를 저장한다는 의미). 그러나 이 작업을 계속 수행하면 KDE의 Baloo의 경우처럼 인덱스된 FS 호스트에 상당한 부담을 줄 수 있습니다. 그렇게 해야 할 설득력 있는 이유가 없다면 나는 그것을 완전히 피하고 여기에 제안된 것과 같은 보다 가벼운 CLI 포인트 검색 유틸리티를 고수할 것입니다.


스크립트 설명:findxattr

  • 잘 알려진 find외부 유틸리티와 해당 관용어를 기반으로 합니다.
    find [options, filters ...] -exec sh -c '[...]' sh_exec "{}" \; 2> dev/null

  • #!/usr/bin/shshebang이 가짜 Bourne 쉘을 가리키는 호스트에서도 POSIX 호환 모드로 실행하면
    /usr/bin/sh --> /usr/bin/bash.

  • 래퍼로 구성됩니다 find. 구현에서 일반적으로 볼 수 있는 모든 부가 기능을 구현하지는 않지만 findOP의 요구 사항을 충족하고 검색 개선에 관심이 있는 ClI 사용자에게 더 많은 유연성을 제공합니다. 특히 다음을 구현합니다.

    • 를 발행하여 findxattr -h|--help올바른 사용법을 문서화하는 "도움말" 모드,
    • 긴 옵션과 짧은 옵션 앞에는 각각 하이픈 1개와 2개가 옵니다.
    • 두 개의 필터 -p|--path-m|--md|--maxdepth, 매우 유사함
      find [-maxdepth <d>] [-path <path_specs>] ...( 참조 man find)
    • 전역 검색 $PWD(인수 없이 호출하거나 를 사용하여 호출하는 경우 -a|--all),
    • x 속성의 KV 속성으로 검색을 표시합니다. 예:
      • 열쇠 -x|--xattr <xattr_name>==,
      • -x|--xattr ==<xattr_value>,
      • 둘 다 -x|--xattr <xattr_name>==<xattr_value>,

    완전히 인용된 경우 x 속성의 이름과 값에 공백이 포함될 수 있습니다.

  • getopt행복하게 구문 분석될 더 많은 옵션과 스위치(스크립트에)를 포함하도록 간단히 확장할 수 있습니다 . 추가 옵션과 필터를 활용하려면 로직을 확장해야 하는데, 기존 옵션을 처리하는 방법은 도구의 범위를 확장하기 위한 청사진과 같습니다.


스크립트 테스트:
먼저 장난감 x 속성을 구축하세요.

$ touch ~/fully/qualified/foo ~/fully/qualified/_1_path/bar ~/fully/qualified/_2_path/foobar ~/fully/qualified/baz

$ setfattr -n user.likes -v 'I like strawberries.' ~/fully/qualified/foo

위에서 는 setfattrx user.__attribute 라는 사용자 네임스페이스를 가리킵니다 likes. 새로운 x 속성은 KV(키-값) 쌍으로 정의됩니다. 여기서 키는 문자열 이며 likes해당 값은 로 시작해야 합니다 .dislikesfilebirth-v

기본적으로 x 속성은 항상 attr다음을 사용하여 사용자 네임스페이스에 생성됩니다 setfattr(및 -v로 대체됨).-V

$ cd ~/fully/qualified
$ attr -s dislikes -V 'hacks' ./foo
$ attr -s filebirth -V '20220627-193029-CEST' ./_1_path/bar
$ attr -s filebirth -V '20210330-185430-CEST' ./_2_path/foobar
$ attr -s dislikes -V 'java' ./baz

도착하다놓다,얻다,제거하다또는목록호환되는 파일 시스템 객체에서도 사용할 수 있는 확장 속성 attr( 참조 man attr):

사용법:
attr [-LRSq] -s attrname [-V attrvalue] pathname # 값 설정
attr [-LRSq] -g attrname pathname # 값 가져오기
attr [-LRSq] -r attrname pathname # attr 삭제 attr
[-LRq ] ] - l 경로 이름 # 속성 목록
-s는 stdin에서 값을 읽고, -g는 stdout에 값을 씁니다.

예를 들면 다음과 같습니다.

$ cd ~/fully/qualified

$ attr -qg likes ./foo
I like strawberries.
$ attr -qg filebirth ./_1_path/bar
20220627-193029-CEST

스크립트는 다음과 같이 탭으로 구분된 출력을 생성합니다.

$ cd ~; pwd
/home/USER

$ findxattr -m 4                             # search entire subtree (from `$PWD`) with max depth of 4    
./fully/qualified/foo        likes        I like strawberries.
./fully/qualified/foo        dislikes     hacks
./fully/qualified/_1_path/bar        filebirth        20220627-193029-CEST
./fully/qualified/_2_path/foobar        filebirth        20210330-185430-CEST
./fully/qualified/baz        dislikes     java

$ findxattr -m 3 -x dislikes==               # search entire subtree (from `$PWD`) by name, depth
./fully/qualified/foo        dislikes     hacks
./fully/qualified/baz        dislikes     java

$ findxattr -m 4 -p "*lified/_2_*" -x filebirth== # search by depth, path, name
./fully/qualified/_2_path/foobar        filebirth        20210330-185430-CEST

$ findxattr -m 4 -x =='20220627-193029-CEST' # search entire subtree (from `$PWD`) by value, depth
./fully/qualified/_1_path/bar        filebirth        20220627-193029-CEST

$ findxattr -x filebirth==                   # search entire subtree (from `$PWD`) by name
./fully/qualified/_1_path/bar        filebirth        20220627-193029-CEST
./fully/qualified/_2_path/foobar     filebirth        20210330-185430-CEST

암호:

#!/usr/bin/sh

#-------------------------------------------------------------
# Author: CBhihe
# Copyright (c) 2022 C. K. Bhihe
# Available under GPL3 at github.com/Cbhihe
#-------------------------------------------------------------

version='0.5.0'

set -o posix
#set -x

getopt_parsed=$(getopt -q -s sh -a -l 'all,help,path:,xattr:,maxdepth:' -o '+ham:p:x:' -- "$@")
exit_code=$?
if [ $exit_code -ne 0 ]; then
    printf "getopt exited with code %d (%s).\n%s\n" $exit_code "getopt parsing error"\
    "The most probable cause is an unknown option. Review command usage with \`findxattr -h|--help'" >&2
    exit 1
fi

eval set -- "$getopt_parsed"
unset getopt_parsed

xattrkey=""
xattrval=""

while true; do
    case "$1" in
        '-a'|'--all')
            /usr/bin/find . -exec sh -c '
                while IFS= read -r xattrkey; do
                    xattrvalout=`/usr/bin/attr -qg "$xattrkey" "$1" 2>/dev/null`
                    printf "%-20s\t%-20s\t%s\n" "$1" "$xattrkey" "$xattrvalout"
                done < <(/usr/bin/attr -ql "$1" 2>/dev/null)
            ' sh_exec "{}" \; 2>/dev/null
            exit 0
        ;;

        '-m'|'--maxdepth'|'--md'|'--maxd')
            tmp=`expr "$2" + 0`
            if (( "$2" == "$tmp" )); then
                maxdepth="$2"
                shift 2
                continue
            else
                printf "The script exited because '--maxdepth' arg must be a positive integer; current arg is %s.\n%s\n" "$2" "Review command usage with \`findxattr -h|--help'" >&2
                exit 1
            fi
        ;;

        '-p'|'--path')
            locpath="$2"
            #if [ "$locpath" = "\(/*[^/]\+\)\+/$" ]; then
            #if expr "$locpath" : "^\(/*\([^/]\)\+\)\+$" >/dev/null; then
            if expr "$locpath" : "^\(/*[^/]\+\)\+$" >/dev/null; then
                shift 2
                continue
            else
                printf "The script exited because '--path' arg must be a valid path; current arg is %s.\n%s\n" "$2" "Review command usage with \`findxattr -h|--help'" >&2
                exit 1
            fi
        ;;

        '-x'|'--xattr')
            keyval="$2"
            found=1
            if [ "$keyval" != "${keyval%==*}" ]; then
                found=0
            fi

            if [ "$found" = "1" ]; then
                printf "The script exited because '-x|--xattr' arg appears to be either empty or malformed.\nReview command usage with \`findxattr -h|--help'. Remember that extended attributes\ncan be sought by key AND value (<key>==<value>), or only by key (<key>==), or only by value\n(==<value>), where in each case the parenthesized content represents the '-x' option's argument.\n" >&2
                exit 1
            else
                xattrkey="${keyval%==*}"
                xattrval="${keyval#*==}"
                shift 2
                continue
            fi
        ;;

        '-h'|'--help')
            printf "%s\n" " " "This is a script based on \`find' but restricted to the options shown below. Both short- and long-" \
"format options are allowed. Unknown options cause the script to abort with exit code 1." \
" " \
"Usage:" \
"   \`findattr -h|--help' Prints this usage information. This option is used alone." \
"   \`findattr -a|--all'  Searches recursively for all files with xattr(s) starting at \$PWD." \
"                        This option is used alone." \
"   \`findattr [-m|maxdepth <d>] [-p|path <path>] [-x|xattr <xattr_name>==<xattr_value>]'" \
"       Options that can be combined:" \
"         -m|--maxdepth  Identical to \`find -maxdepth <d>' option, where \`d' a positive integer;" \
"                        Limits any recursive search with \`find', to the specified level of the file tree." \
"                        Note that the level of the file tree is understood counting from \$PWD, NOT" \
"                        from a supposed start point represented by the \`--path' argument if present." \
"         -p|--path      Identical to \`find -path <spath>' option;" \
"                        Traverse the file tree from the specified path, searching for ANY xattr," \
"                        unless the \`--xattr' option is invoked to filter the search so a specific xattr" \
"                        name and value can be sought." \
"         -x|--xattr     Lists files with specified \`xattr', n the file tree starting at \$PWD unless" \
"                        \`--path' is invoked." \
"                        A compulsory argument of the form: '<xattr_name>==<xattr_value>' is expected." \
"                        Quoting is needed in case the argument contains space(s) or special characters." \
" "
            exit 0
        ;;

        '--')
            shift
            break
        ;;

        *)
            printf "%s\n" "Internal error. Abort." >&2
            exit 1
        ;;

    esac
done

if [ -n "$maxdepth"  ] && [ -n "$locpath" ]; then
    set -- -maxdepth "$maxdepth" -path "$locpath"
elif [ -z "$maxdepth"  ] && [ -n "$locpath" ]; then
    set -- -path "$locpath"
elif [ -z "$maxdepth"  ] && [ -z "$locpath" ]; then
    set --
else
    #[ -n "$maxdepth"  ] && [ -z "$locpath" ]
    set -- -maxdepth "$maxdepth"
fi

if [ -n "$xattrkey" ] && [ -n "$xattrval" ]; then
#if expr "$xattrkey" != "" >/dev/null && expr "$xattrval" != "" >/dev/null; then
    xattrkey="$xattrkey" xattrval="$xattrval" /usr/bin/find . "$@" -exec sh -c '
        xattrvalout=`/usr/bin/attr -qg "$xattrkey" "$1" 2>/dev/null`
        if [ "$xattrvalout" = "$xattrval" ]; then
        #if expr "$xattrvalout" = "$xattrval" >/dev/null; then
            printf "%-20s\t%-20s\t%s\n" "$1" "$xattrkey" "$xattrvalout"
        fi
    ' sh_exec "{}" \; 2>/dev/null

elif [ -n "$xattrkey" ] && [ -z "$xattrval" ]; then
#elif expr "$xattrkey" != "" >/dev/null && expr "$xattrval" = "" >/dev/null; then
    xattrkey="$xattrkey" xattrval="$xattrval" /usr/bin/find . "$@" -exec sh -c '
        xattrvalout=`/usr/bin/attr -qg "$xattrkey" "$1" 2>/dev/null`
        if [ -n "$xattrvalout" ]; then
            while IFS= read -r xattrvalout || [ -n "$xattrvalout" ]; do
                printf "%-20s\t%-20s\t%s\n" "$1" "$xattrkey" "$xattrvalout"
            done <<<"$xattrvalout"
        fi
    ' sh_exec "{}" \; 2>/dev/null

elif [ -z "$xattrkey" ] && [ -z "$xattrval" ]; then
#elif expr "$xattrkey" = "" >/dev/null && expr "$xattrval" = "" >/dev/null; then
    /usr/bin/find . "$@" -exec sh -c '
        xattrkeys=`/usr/bin/attr -ql "$1" 2>/dev/null`
        if [ -n "$xattrkeys" ]; then
            while IFS= read -r xattrkey || [ -n "$xattrkey" ]; do
                xattrvalouts=`/usr/bin/attr -qg "$xattrkey" "$1" 2>/dev/null`
                if [ -n "$xattrvalouts" ]; then
                    while IFS= read -r xattrvalout || [ -n "$xattrvalout" ]; do
                        printf "%-20s\t%-20s\t%s\n" "$1" "$xattrkey" "$xattrvalout"
                    done <<<"$xattrvalouts"
                fi
            done <<<"$xattrkeys"
        fi
    ' sh_exec "{}" \; 2>/dev/null

else
    # [ -z "$xattrkey" ] && [ -n "$xattrval" ]; then
    # expr "$xattrkey" = "" >/dev/null && expr "$xattrval" != "" >/dev/null
    xattrkey="$xattrkey" xattrval="$xattrval" /usr/bin/find . "$@" -exec sh -c '
        xattrkeys=`/usr/bin/attr -ql "$1" 2>/dev/null`
        if [ -n "$xattrkeys" ]; then
            while IFS= read -r xattrkey || [ -n "$xattrkey" ]; do
                xattrvalouts=`/usr/bin/attr -qg "$xattrkey" "$1" 2>/dev/null`
                if [ -n "$xattrvalouts" ]; then
                    while IFS= read -r xattrvalout || [ -n "$xattrvalout" ]; do
                        if [ "$xattrvalout" = "$xattrval" ]; then
                            printf "%-20s\t%-20s\t%s\n" "$1" "$xattrkey" "$xattrvalout"
                        fi
                    done <<<"$xattrvalouts"
                fi
            done <<<"$xattrkeys"
        fi
    ' sh_exec "{}" \; 2>/dev/null

fi

exit 0

관련 정보