尋ねる
私はバッシュを使います。ファイルを見つけるときは、通常、次のことを行います。
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を実行する簡単な1行方法はありますか?こんなことが起きているので参考にしてください後ろに注文する
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
または何でも)にパイプする1行ファイルの作成に焦点を当てます。私の場合は、最初に送信し、後で送信したいと思いますfind
(言えば)。私のキャプチャ/使用は厳密に次のとおりです後ろに。 - 「Lindコマンドの最後の出力を再利用します。」ビューには良いですが、コマンドだけを繰り返すようで、キャプチャについては言及しません。N番目出力ライン。正直怖いです。
- 「Bashの内蔵マルチライン出力キャプチャ」近いですが十分ではありません。
- 「ターミナル、シェル、tty、コンソールなどの正確な違いは何ですか?」この本は確かに読みやすい本です。
ご協力ありがとうございます!私が90年代の10代だったときに* nix / BSDを使用しましたが、疲れて気分が悪い隣人がプラグアンドプレイサウンドカード用のドライバをインストールするのを手伝ってくれたので、コマンドについて話し合ってうれしかったです。 - 詳細を(明らかに)あまり怖い個人に関連付けます。また帰ってきて気分が良すぎます。
答え1
これはあなたの問題に対する潜在的な解決策です合理的にファンキーなファイル名があっても(完全ではありませんが)安全です(改行文字を含むファイル名を処理しません。おそらく変更できますが、他の問題は隠れている可能性があります)。
2つの関数のうち最初の関数は渡された引数find
で実行され、出力を配列に保存して表示します。 2番目は配列にアクセスするためのヘルパーです。
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の上に 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
}