egrep结果以vim作为行参考文件列表

时间:2012-07-27 17:29:08

标签: bash shell vim grep

在shell中,我使用以下函数创建文件列表并将其传递给vim。

感觉还好,但我丢失了行参考,我按正确的顺序打开文件,但是当光标从第一行开始时我必须再次搜索文本。

〜/ .bashrc上的实际功能

function vimgrep(){
   vim `grep -IR "$1" * | awk -F: '$1!=f{print ""$1"";f=$1}' | grep -v 'Test\|test'` +ls
}

function vimgrep2(){
   vim `grep -IR "$1" * | awk -F: '$1!=f{print ""$1"";f=$1}' ` +ls
}

Obs。:filelist必须来自shell到vim,然后它必须保留缓冲文件的行引用,就像结果:make当它捕获任何错误时(但没有底部窗口[:cwindow] )。

编辑: 好的...不是那么优雅,但我可以将搜索到的字符串传递给vim为+ /" $ 1",如:

   vim `grep -IR "$1" * | awk -F: '$1!=f{print ""$1"";f=$1}' ` +/"$1"

如果脚本没有使用临时文件会更好。

5 个答案:

答案 0 :(得分:1)

使用带有外部Grep的行号

据我所知,使用行号选项标志一次打开多个文件是不可能的,因为Vim只会将标志应用于列表中的第一个文件。该手册页说:

 +[num]      For the first file the cursor will be positioned on line  
             "num". If "num" is missing, the cursor will be positioned
             on the last line.

因此,您可以一次调用每个文件上的函数,或者将函数调用放在一个循环中,该循环一次操作两个位置参数(文件名和正则表达式)。前者当然更容易。例如:

vimgrep () {
    local file="$1"
    shift || return 1
    vim +$(egrep -n "$1" "$file" | cut -d: -f1) "$file"
}

# Sample function call.
vimgrep /etc/password '^www-data'

答案 1 :(得分:1)

有了这个,您可以通过cncpcc在匹配之间移动..等等:

function vimgrep(){
   vim -c "exec(\"grep $1 *\")"
}

突出显示:

function vimgrep(){
   vim -c "exec(\"grep -IR $1 *\")" -c "let @/='$1'" -c "set hls"
}

答案 2 :(得分:1)

免责声明:我对vim

一无所知

手册页用+<line no>这样的参数说明它将跳转到提供文件的那一行。基于这些信息,我掀起了这个脚本。它依赖于如下命令行来启动vim:

$ vim +n1 file1 +n2 file2

您也可以将它作为shell函数放在'~/.bashrc中,因为它非常小。

用法: vimgrep -e <search pattern> <fileglob>

搜索模式可以是grep理解的任何正则表达式,而文件glob是bash理解的shell glob。

#!/bin/bash

# set -o xtrace # uncomment to debug

# declare variables
declare -a grepopts files

[[ $1 =~ -e$ ]] && grepopts+=("-e") && grepopts+=("$2") && shift 2

files=("${@}")

vim $(egrep -n -m1 -H "${grepopts[@]}" "${files[@]}" | \
        sed -e 's/^\(.\+\):\([0-9]\+\):.\+$/+\2 \1/')

警告:如果文件名中包含:字符,则此脚本将失败。

答案 3 :(得分:1)

以下是一些能够为您提供所需内容的功能。它将在缓冲区中打开每个文件,并将行设置为与给定正则表达式匹配的第一行。

我倾向于喜欢这样的简短描述性bash函数,因为bash很难在不使用大量代码的情况下理解。

唯一的缺陷就是它没有有效地过滤掉二进制文件。对find_nonbinary函数的更新将解决此问题。

这些是辅助函数。它们不能直接运行。

# Using print0 to handle files with weird names.
# This is just a quick placeholder.
# You can play with this to get better results.
function __find_nonbinary() {
    find -type f -print0
}

function __generate_vim_cmds() {
    xargs -0 awk -v regex="$regex" \
        '$0 ~ regex {printf "e +%s %s\n", FNR, FILENAME; nextfile}'
}

function __combine_vim_cmds() {
    declare -a vim_cmds

    while read line; do
        vim_cmds+=( " $line " )
    done

    # Force subshell to prevent IFS from being clobbered.
    (
        IFS="|"
        echo "${vim_cmds[*]}"
    )
}

这是要使用的实际功能。

function vimgrep() {
    local regex="$1"

    if [[ -z "$regex" ]]; then
        echo "Usage: $0 regex" 1>&2
        exit 1
    fi

    local vim_cmds=$(
        __find_nonbinary    |
        __generate_vim_cmds |
        __combine_vim_cmds
    )

    if [[ -z "$vim_cmds" ]]; then
        echo "No files matching $regex found." 1>&2
        exit 1
    fi

    vim -c "$vim_cmds"
}

答案 4 :(得分:1)

Vim还附带了一个vimgrep命令,您可以使用

function vimgrep() {
    local regex="$1"

    if [[ -z "$regex" ]]; then
        echo "Usage: $0 regex" 1>&2
        exit 1
    fi

    vim -c "vimgrep /$regex/ **"
}

小心在它下面有很多文件的目录中运行它。