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
findme
grep
이는 결과를 추출하는 기능의 변형이지만 결과에 번호를 매기거나 페이지를 매기는 대신 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