묻다
저는 배쉬를 사용합니다. 파일을 찾을 때 일반적으로 다음을 수행합니다.
find -name stackexchange.hs
결과는 일반적으로 다음과 같습니다.
/youre/the/man/now/dog/stackexchange.hs
/you/are/no/longer/the/dog/dog/stackexchange.hs
/this/is/the/file/i/want/stackexchange.hs
그런 다음 다음 중 하나를 수행하고 싶습니다.
- 옵션 1: 결과 목록의 마지막 항목 열기윔.
- 옵션 2: 결과 목록에서 N번째 항목 열기윔.
현재는 잘라내기 및 붙여넣기에 마우스를 사용하고 있습니다. 이건 내 기억을 생각나게 해질문:
- 옵션 1과 2를 수행하는 간단한 한 줄 방법이 있습니까? 이런 일이 벌어지고 있으니 참고하세요뒤쪽에주문하다
find
. - 일종의 bash 벡터/배열로 stdout에서 N 줄을 캡처하는 방법이 있습니까?
이상적인 사용
$ find -name am_i_really_all_alone.txt
./borges/library/you_are_not_alone.txt
./borges/library/am_i_really_all_alone.txt
$ vim (N)
(구문과 의미는 다를 수 있지만 아이디어를 얻으실 수 있습니다)
유사점
비슷한 질문이 여러 개 있는 것 같습니다. 이 내 꺼야인지된차이점(저는 영감을 받을 수 있습니다):
- "발견된 파일을 열려면 find 명령을 사용하십시오"파일 이름을 파이프
find
(vim
또는 무엇이든)에 파이프하는 한 줄 파일을 만드는 데 집중하세요. 제 경우에는 먼저 전송하고 나중에 전송하고 싶습니다find
(말하자면). 내 캡처/사용은 엄격하게 다음과 같습니다뒤쪽에. - "Lind 명령의 마지막 출력을 재사용합니다."보기에는 좋지만 명령만 반복하는 것 같고 캡처에 대해서는 언급하지 않습니다.N번째출력 라인. 솔직히 두렵습니다.
- "Bash의 내장 여러 줄 출력 캡처"가깝지만 충분하지는 않습니다.
- "터미널, 쉘, tty, 콘솔 등의 정확한 차이점은 무엇입니까?"이 책은 참으로 읽기 좋은 책이다.
당신의 도움을 주셔서 감사합니다! 제가 90년대 10대였을 때 *nix/BSD를 사용했는데 지치고 기분 나쁜 이웃이 플러그 앤 플레이 사운드 카드용 드라이버 설치를 도와달라고 전화해서 명령에 대해 논의하게 되어 기뻤습니다. - 세부 사항을 (분명히) 덜 무서운 개인과 연관시키십시오. 다시 돌아와서 기분이 너무 좋아요.
답변1
이는 귀하의 문제에 대한 잠재적인 해결책이며합리적으로펑키한 파일 이름이 있어도 (완전하지는 않지만) 안전합니다(개행 문자가 있는 파일 이름을 처리하지 않습니다. 아마도 수정할 수 있지만 다른 문제가 숨어 있을 수 있습니다).
두 개의 함수 중 첫 번째 함수는 find
전달한 인수로 실행되고 출력을 배열에 저장하고 표시합니다. 두 번째는 배열에 액세스하기 위한 도우미일 뿐입니다.
myfind() {
IFS=$'\n' __last_find_result=($(find "$@"));
printf "%s\n" "${__last_find_result[@]}";
}
myget() {
echo "${__last_find_result[$1]}";
}
사용 사례:
$ myfind . -name "c*"
./a b/c d
./.git/config
./.git/hooks/commit-msg.sample
$ vim "$(myget 0)"
# This opens the "./a b/c d" file.
$ vim "$(myget 2)"
# This opens ".git/hooks/commit-msg.sample"
$(myget index)
파일 이름에 공백이나 기타 문제가 되는 문자가 없으면 주위에 따옴표가 필요하지 않습니다.
전체 출력을 find
사용자 환경에 푸시합니다. 이는 제한될 수 있습니다. (배열 대신 임시 파일을 사용하면 이 문제가 해결되지만 다른 문제가 있습니다. 특히 여러 셸을 동시에 사용하는 경우가 그렇습니다.)
답변2
나는 이것에 이것을 가지고 있습니다 .screenrc
:
bind -c pasteline 1 eval copy 'stuff "-Y"' 'paste .'
bind -c pasteline 2 eval copy 'stuff "2-Y"' 'paste .'
bind -c pasteline 3 eval copy 'stuff "3-Y"' 'paste .'
bind -c pasteline 4 eval copy 'stuff "4-Y"' 'paste .'
bind -c pasteline 5 eval copy 'stuff "5-Y"' 'paste .'
bind -c pasteline 6 eval copy 'stuff "6-Y"' 'paste .'
bind -c pasteline 7 eval copy 'stuff "7-Y"' 'paste .'
bind -c pasteline 8 eval copy 'stuff "8-Y"' 'paste .'
bind -c pasteline 9 eval copy 'stuff "9-Y"' 'paste .'
bindkey ¬ command -c pasteline
기본적으로 화면에서는 , ¬1커서 위에 줄을 붙여넣고, ¬2, 커서 위에 두 번째 줄을 붙여넣는 식으로 진행됩니다. 10행 이상에 대해 더 추가하고 싶을 수도 있지만 행 7 이후에는 screen
원하는 행 수를 얻기 위해 행 수를 계산하는 것보다 마우스나 복사 모드를 사용하는 것이 더 좋습니다.
답변3
또 다른 해결책: 선택 사항을 자동으로 묻는 대화형 스크립트를 작성할 수 있습니다. 대화형 스크립트의 코드는 다음과 같습니다.
#!/bin/bash
echo "enter your choice : z for last argument or a number for that file"
read choice
case "$choice" in
z) eval vim \$$#;;
*)eval vim \$$choice;;
esac
이 스크립트를 "autofind"와 같은 이름으로 저장하고 "find command"를 인수로 사용하여 스크립트를 호출합니다. 다음은 스크립트를 호출하는 코드입니다.
./autofind `your find command`
그러나 스크립트를 사용하기 전에 "find 명령"이 결과를 제공하는지 확인하십시오. 결과가 표시되면 스크립트를 사용하십시오.
답변4
Matz의 대답은 정확히 내가 원했던 것이었습니다. 더 많은 가져오기 옵션을 허용하기 위해 그의 코드를 약간 확장했습니다.
$ f ~/scripts -name '*.sh'
$ vim $(g foo) # edit all find results matching "foo"
$ vim $(g 1 3 5) # edit find results number 1, 3 and 5
$ vim $(g 3-5) # edit find results 3-5
$ vim $(g 5-) # edit find results 5 to last
$ vim $(g -7) # edit find result 7 from bottom
$ vim $(g 1 4-5 -7 9- foo) # all of the above combined
.
f() {
IFS=$'\n' __last_find_result=($(find "$@"));
printf "%s\n" "${__last_find_result[@]}";
}
g() {
len=${#__last_find_result[@]}
pad=${#len}
numbers=""
if [ "$1" == "-n" ]; then
numbers=1
shift
fi
if [ -z "$1" ]; then
if [ -n "$numbers" ]; then
n=1;
for e in "${__last_find_result[@]}";do
printf "%0${pad}d. %s\n" "$n" "$e"
let n=n+1
done
else
printf "%s\n" "${__last_find_result[@]}"
fi
else
for l in $@;do
if [[ "$l" =~ ([^0-9-]+) ]];then
n=1;
for e in "${__last_find_result[@]}";do
if [[ $e =~ $1 ]]; then
if [ -n "$numbers" ];then
printf "%0${pad}d. %s\n" "$n" "$e"
else
printf "%s\n" "$e"
fi
fi
let n=n+1
done
elif [[ "$l" =~ ^([0-9]+)$ ]];then
let l=l-1
echo "${__last_find_result[$l]}";
elif [[ "$l" =~ ^([0-9]*)(-)?([0-9]*)$ ]]; then
from=${BASH_REMATCH[1]};
dash=${BASH_REMATCH[2]};
to=${BASH_REMATCH[3]};
if [ -z "$from" ]; then # -n
[ $to -gt ${#__last_find_result[@]} ] && to=${#__last_find_result[@]}
echo "${__last_find_result[-$to]}";
else # n-m
[ -z "$to" ] && to=${#__last_find_result[@]}
[ $to -gt ${#__last_find_result[@]} ] && to=${#__last_find_result[@]}
let to=$to-1
let from=$from-1
n=$(($from+1))
for i in `seq $from $to`;do
if [ -n "$numbers" ];then
printf "%0${pad}d. %s\n" "$n" "${__last_find_result[$i]}"
else
printf "%s\n" "${__last_find_result[$i]}"
fi
let n=n+1
done
fi
fi
done
fi
}