Bash

從 grep 輸出自動完成

  • January 26, 2016

我怎樣才能更容易地使用找到的文件名grep作為參數vim

$ grep -r foo *
lib/beatles/john.c
lib/pantera/phil.c
lib/pinkfloyd/roger.c
lib/pinkfloyd/richard.c
lib/whitestripes/elephant/jack.c

$ vim lib/pinkfloyd/roger.c

要使用 Bash 自動完成,我需要輸入**“** l \tp \ti \tr \to \t ,因為許多其他文件都匹配。有沒有更簡單的方式說“給我找到的第三個文件?” 也許是其中之一:

$ vim $3        // Third line
$ vim 'roger'   // Only line with string 'roger'
$ vim TabTabTab // Each Tab completes a different filename from grep

我確實使用 Tmux,我知道我可以上去選擇文件名然後粘貼它。但這仍然有點笨拙,即使作為 VIM 使用者。肯定有更好的辦法!

請注意,我不是在尋找編寫 grep 輸出腳本的解決方案,而是在使用 VIM grep 和打開文件時手動使用它。

**編輯:**我正在尋找一個通用的解決方案,而不是總是針對“羅傑”或始終針對第三項的解決方案。

我製作了一個腳本來遞歸地 grep 模式,然後我可以選擇其中一個匹配項,以便 vim 將在該行中打開該文件。我稱之為vgrep(vim grep,雖然它也在其中使用awk)。以下是它的程式碼:

#!/bin/bash
my_grep() {
       grep -Rn -I --color=auto --exclude-dir={.svn,.git} --exclude={tags,cscope.out} "$@" . 2>/dev/null
}
my_grep_color() {
       grep -Rn -I --color=always --exclude-dir={.svn,.git} --exclude={tags,cscope.out} "$@" . 2>/dev/null
}

awk '{
   print NR, $0
}' <(my_grep_color "$@")

awk '{
   lines[NR]=$1;
}

END{
   printf "Enter index: "
   getline num < "-";
   split(lines[num], s, ":")
   system("vim "s[1]" +"s[2])
}' <(my_grep "$@")

我呼叫grep了兩次只是為了突出顯示我的比賽,你可以改變它,讓它只被呼叫一次,但你會失去突出顯示。

用法:

假設你想在其中有一個單詞“Foo”的那一行打開 vim,你可以像這樣使用它:vgrep Foo

如果有一個文件 foobar 像:

a b c
Bar
e f Foo g
h i

vgrep將輸出:

1 ./foobar:3 e f Foo g
Enter index: 

所以你可以輸入1+ enter,它會在第三行打開那個文件。它將為它找到的每個匹配輸出一個索引行。

我很確定這個腳本可以改進,但對於我的使用來說它工作得很好。


此外,如果您正在使用ctagscscopeC/C++ ,請考慮使用.

引用自:https://unix.stackexchange.com/questions/256016