コマンドを見つけ、出力を列挙して選択を許可しますか?


10

を使用するとfind、多くの場合、次のような複数の結果が見つかります

find -name pom.xml
./projectA/pom.xml
./projectB/pom.xml
./projectC/pom.xml

特定の結果のみを選択したい場合があります(例:)edit ./projectB/pom.xmlfind出力を列挙し、別のアプリケーションに渡すファイルを選択する方法はありますか?お気に入り:

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」を使用しても、かなりうまくいくようです。例:

  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
  }

されたYour find command | head -TheNumberYouWant要件を満たしますか?(あなたの行:!! | head -2 | xargs myEditor
ADDB 2017

1
fzfをチェックしてください。これは、この種のアクションを^ T(デフォルト)にバインドします
Tavian Barnes

回答:


16

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[@]}"

4
私が疑うものを提供するための+1は非常にほとんど使用されていないコマンド動詞
roaima

私はそれに取り組んでいます。 selectを変更してもうまく配置されないようですIFS
DopeGhoti 2017

3
ああ。( IFS=$'\n'; select file in $(find -maxdepth 2 -name '*.txt'); do echo "$file"; done; )
roaima 2017

Cスタイルの文字列について考えるべきだった。よくやった!
DopeGhoti 2017

1
:私はいくつかの洞察力、@roaimaいただければと思います unix.stackexchange.com/questions/378282/...
DopeGhoti

3

ファイル名に改行や他の非印刷文字が含まれていない場合、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

手軽に、明示的なファイル名pom.xmlに空白が含まれることはありません(:
DopeGhoti 2017

上記にバグがあるようです。find -name pom.xmlは多くの出力を提供しますが、findnumは1行しか提供しません。例:./features/org.eclipse.swt.tools.feature/pom.xml ./examples/org.eclipse.swt.examples.ole.win32/pom.xml ./examples/org.eclipse.swt.examples/pom .xml ./examples/org.eclipse.swt.examples.views/pom.xml ./examples/org.eclipse.swt.examples.launcher/pom.xml ./examples/org.eclipse.swt.examples.browser。 demos / pom.xml ./local-build/local-build-parent/pom.xml
Leo Ufimtsev

同じデータセットで@Leoはどのように使用しましたfindnumか?
roaima 2017

うまくいけば、このスクリーンショットは、問題を説明するのに役立ちます:i.imgur.com/hfneWJn.png あなたはは、Feature.xml利回り3件の結果ということを観察することができます。findnum機能を使用すると、エラーが発生します。Fundnum pom.xmlでは、1つの結果のみが出力されますが、find -name pom.xmlは3つの結果を出力します。データセットを取得する方法を説明するために質問を更新しました。(これは単純なgitリポジトリです)
Leo Ufimtsev 2017

1
@DopeGhoti、ただし、空白スペースd:で名前が付けられたディレクトリにある可能性があります
ワイルドカード

3

総出力の先頭を取得し、-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行目を取得します。


1
さて、シンプルなソリューションが最善のようです。「nl」と「$(!!)」を組み合わせたあなたの答えは、実際にはかなりうまくいくようです。質問に詳細を投稿しました。ご返信ありがとうございます。
レオUfimtsev 2017

1

検索後にファイルを編集することが目的の場合は、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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.