"찾기" 결과 중 하나를 선택하고 지정된 응용 프로그램으로 여는 방법

"찾기" 결과 중 하나를 선택하고 지정된 응용 프로그램으로 여는 방법

findme다음 코드로 호출되는 bash 스크립트가 있습니다 .

#!/bin/bash
locate -Abi '*\.'$1 $2 | grep --color=always -ni $2 | less -R

파일 이름(다음 인수 제공)에 패턴이 있고 지정된 파일 확장자(스크립트에 제공된 첫 번째 인수)가 있는 모든 파일을 검색합니다.
다음 명령을 실행하면:

user@machine$ findme pdf classifi

pdf가 포함된 모든 파일을 검색합니다 . classifi그래서 나는 다음과 같은 것을 얻을 수 있습니다.

1:/홈/사용자/Dropbox/SharedWithFriends/수학/분류cations2000.pdf
2:/home/user/Dropbox/SharedWithFriends/math/분류양이온2010.pdf

문제는 다음과 같습니다 "다음 작업을 자동화하기 위해 결과를 표시한 후 숫자와 뷰어를 요청하는 bash 스크립트 코드를 제공해 주실 수 있나요?"

예를 들어, 다음을 입력하면:

> 2 evince

검색결과의 2번째 항목에 대해 스크립트가 실행되며 evince,2, 이것이 이전 검색 결과에 입력한 내용이라면 다음과 같습니다.

evince /home/user/Dropbox/SharedWithFriends/math/classifications2010.pdf

답변1

findmegrep이는 결과를 추출하는 기능의 변형이지만 결과에 번호를 매기거나 페이지를 매기는 대신 less내부 배열에서 결과를 나열한 다음 프로젝트와 프로그램을 선택하라는 메시지를 표시합니다.

#!/usr/bin/env bash

readarray -O 1 -t results < <(locate -Abi '*\.'"$1" "$2" | grep --color=always -i "$2")

for((i=1; i <= ${#results[*]}; i++))
do
  printf "%d: %s\n" $i "${results[i]}"
done
read -p "> " item program
$program "${results[item]}"

파일 이름과 grep 매개변수의 공백을 더 잘 처리하기 위해 원본 스크립트에 몇 가지 따옴표를 추가했습니다. readarray결과가 0이 아닌 인덱스 1에서 시작하여 grep의 번호에 해당하도록 호출을 조정했습니다 .

답변2

스크립트 findme에 몇 가지 문제가 있습니다 .

  • 변수 대체에 큰따옴표가 누락되었습니다.
  • 의 출력은 grep --color=always명령 대체에 사용할 수 없는 결과를 생성합니다. 를 전달하려면 필요 less하지만 스크립트에서 재사용하려고 하지 마세요.
  • grep과 찾기는 다른 패턴 구문을 사용하므로 grep색상 지정에 두 번째 인수를 사용하는 것이 항상 작동하는 것은 아닙니다. -r에 전달하면 locate정규식을 사용하게 되지만 Emacs 구문은 grep이 지원하는 구문과 약간 다릅니다.

Bash에서는 다음을 사용할 수 있습니다.mapfile일부 행을 배열에 안정적으로 채웁니다. 그것을 결합하다프로세스 교체명령의 출력을 사용하십시오. 그런 다음 배열을 인쇄하고 사용자의 입력을 읽습니다.

findrun () {
  mapfile search_hits <(locate -Abir ".*\.$1" "$2")
  print '%s\n' "${search_hits[@]}" | grep --color=always -ine "$2"
  if read -a cmd; then
    set -- "${cmd[@]}"
    set -- "$@" "${search_hits[$1]}"
    shift
    "$@"
  fi
}

또 다른 인터페이스는 위치 매개변수를 설정하는 것입니다. 함수에서 위치 매개변수를 변경할 수 없기 때문에 이는 약간 까다롭지만Bash에서 로터리 방식으로 이 작업을 수행합니다.별칭을 사용하고 스크립트를 가져옵니다. 따옴표를 조심하세요.

alias findrun='. <(echo findrun_prepare \"\$@\"; echo set -- "\"\${search_hits[@]}\"")'
findrun_prepare () {
  mapfile search_hits <(locate -Abir ".*\.$1" "$2")
  print '%s\n' "${search_hits[@]}" | grep --color=always -ine "$2" >&2
}

용법:

findrun pdf classifi
evince "$2"

답변3

Jeff Schaller가 제공한 솔루션을 기반으로 합니다. 해결책을 찾았으며 더 나은 개선을 위해 귀하의 의견을 기꺼이 받아들일 것입니다.

#!/bin/bash

readarray -O 1 -t results < <(locate -Abi '*\.'"$1" "$2")

for((i=1; i <= ${#results[*]}; i++))
do
  printf "%d: %s" $i "${results[i]}" | grep --color=always -i "$2"
done

read -p "> " item program

$program "${results[item]}"

이는 간단한 답변처럼 보일 수 있습니다(주제의 복잡성에 따라 다름).

하지만 결과가 특정 수치를 초과하면 충분하지 않습니다! 이 경우에는 다음 more과 같은 것이 필요합니다.less

관련 정보