find
を使用すると、多くの場合、次のような複数の結果が見つかります
find -name pom.xml
./projectA/pom.xml
./projectB/pom.xml
./projectC/pom.xml
特定の結果のみを選択したいことがよくあります(例:edit ./projectB/pom.xml
)。 find
出力を列挙し、別のアプリケーションに渡すファイルを選択する方法はありますか?お気に入り:
find <print line nums?> -name pom.xml
1 ./projectA/pom.xml
2 ./projectB/pom.xml
3 ./projectC/pom.xml
!! | <get 2nd entry> | xargs myEditor
?
[編集]言及した解決策のいくつかを使って、いくつかの特有のバグにぶつかった。だから私は再現する手順を説明したいと思います:
git clone http://git.Eclipse.org/gitroot/platform/Eclipse.platform.swt.git
cd Eclipse.platform.swt.git
<now try looking for 'pom.xml' and 'feature.xml' files>
[編集]解決策1これまでのところ、「nl」(列挙型出力)の組み合わせで、ヘッドとテールを関数に組み合わせて$(!!)を使用すると機能するようです。
つまり:
find -name pom.xml | nl #look for files, enumirate output.
#I then define a function called "nls"
nls () {
head -n $1 | tail -n 1
}
# I then type: (suppose I want to select item #2)
<my command> $(!!s 2)
# I press enter, it expands like: (suppose my command is vim)
vim $(find -name pom.xml |nls 2)
# bang, file #2 opens in vim and Bob's your uncle.
[編集]解決策2「select」の使用も同様にうまく機能するようです。 e.x:
findexec () {
# Usage: findexec <cmd> <name/pattern>
# ex: findexec vim pom.xml
IFS=$'\n';
select file in $(find -type f -name "$2"); do
#$EDITOR "$file"
"$1" "$file"
break
done;
unset IFS
}
bash
の組み込みselect
を使用:
IFS=$'\n'; select file in $(find -type f -name pom.xml); do
$EDITOR "$file"
break
done; unset IFS
コメントに追加された「ボーナス」質問の場合:
declare -a manifest
IFS=$'\n'; select file in $(find -type f -name pom.xml) __QUIT__; do
if [[ "$file" == "__QUIT__" ]]; then
break;
else
manifest+=("$file")
fi
done; unset IFS
for file in ${manifest[@]}; do
$EDITOR "$file"
done
# This for loop can, if $EDITOR == vim, be replaced with
# $EDITOR -p "${manifest[@]}"
ファイル名に改行や他の非印刷文字が含まれていない場合、2つの小さな関数がこれを解決するのに役立ちます。 (スペースを含むファイル名は処理します。)
findnum() { find "$@" | sed 's!^\./!!' | nl; }
wantnum() { sed -nr "$1"'{s/^\s+'"$1"'\t//p;q}'; }
例
findnum -name pom.xml
1 projectA/pom.xml
2 projectB/pom.xml
3 projectC/pom.xml
!! | wantnum 2
projectB/pom.xml
総出力の先頭を取得し、-1でテールすることができます。これは他のコマンドやエディタなどで出力をパイプすることができます。
(100行取得して、最後に100行を出力してください)find。 |ヘッド-100 |尾-1
xxx@prod01 (/home/xxx/.ssh) $ find .
.
./authorized_keys
./id_rsa
./id_rsa.pub
./id_rsa_b_x.pub
./id_rsa_a_y.pub
./known_hosts
xxx@prod01 (/home/xxx/.ssh) $ find . | head -3
.
./authorized_key
./id_rsa
xxx@prod01 (/home/xxx/.ssh) $ find . | head -3 | tail -1
./id_rsa
eg: vim "$(find . | head -100 | tail -1)"
発見の100行目を取得します。
検索後にファイルを編集することが目的の場合は、 sag/sack を試してください。
例:
$ sag skb_copy
sack__option is: -ag
============> running ag! <============
===> Current Profile: no_profile
===> Using flags:
===> Searching under: /home/fklassen/git/pvc-appliance/kernel/drivers/ixgbevf
===> Searching parameters: skb_copy
/home/fklassen/git/pvc-appliance/kernel/drivers/ixgbevf/kcompat.c
[1] 195: skb_copy_bits(skb, offset, buffer, len) < 0)
/home/fklassen/git/pvc-appliance/kernel/drivers/ixgbevf/kcompat.h
[2] 1774: if (skb_copy_bits(skb, offset, buffer, len) < 0)
[3] 2321:#define skb_copy_to_linear_data(skb, from, len) \
[4] 2323:#define skb_copy_to_linear_data_offset(skb, offset, from, len) \
...次に、最後の検索結果を編集します....
F 4
利点は、後で戻って最初の検索結果を編集できることです
F 1