我正在尝试在我的外壳上创建一个宏。
我试图自动化的操作是这样的:
Find all the files containing TEXT_TO_SEARCH, and open them with VSCODE
我可以用一行字做到这一点
$ code `git grep TEXT_TO_SEARCH | cut -d: -f1 | sort -u`
所以我的第一步是将以下函数添加到~/.zshrc
cgrep() {
code `git grep "$1" | cut -d: -f1 | sort -u`
}
进而
$ cgrep TEXT_TO_SEARCH
这有效。
现在我正在尝试添加一个额外的功能:
Before opening each file with VSCode, echo to the console "Opening FILE_NAME"
首先我尝试过这个
cgrep() {
grep_results=`git grep "$1" | cut -d: -f1 | sort -u`
for file in $grep_results; do
echo "Opening $file"
code $file
done
}
请注意,这grep_results
是一个“垂直列表”,即
$ echo $grep_results
src/path1/FILE1.py
src/path2/FILE2.py
src/path3/FILE3.py
这样,for 循环将第一个视为file
整体grep_results
并打开FILE3.py
(不是src/path3/FILE3.py
)。
我也尝试过这个(在GPT的帮助下)
cgrep() {
grep_results=`git grep "$1" | cut -d: -f1 | sort -u`
echo "$grep_results" | while read -r file; do
echo "Opening $file"
code "$file"
done
}
这样我可以只打开第一个 grep 文件,然后我从 VSCode 收到一条我不想要的消息,但我实际上并不理解
$ cgrep TEXT_TO_SEARCH
Opening src/path1/FILE1.py
Run with 'code -' to read from stdin (e.g. 'ps aux | grep code | code -').
答案1
git grep TEXT_TO_SEARCH | cut -d: -f1 | sort -u
您可以将其简化为
git grep -l TEXT_TO_SEARCH
您不需要排序步骤,因为列表不会多次包含相同的文件名,并且git grep
(与grep -r
)在实践中生成排序列表。
grep_results=`git grep …`
您将文件名列表放入字符串中。使用大批反而。输入是一个换行符分隔的列表,因此告诉 zsh (默认情况下它也会将空格、制表符和 nul 视为分隔符,这会破坏包含空格或制表符的文件名),使用f
参数扩展标志。
grep_results=( ${(f)"$(git grep -l -- TEXT_TO_SEARCH)"} )
您可以使该代码与文件名中的换行符一起使用(这对于您的情况可能重要也可能不重要)。告诉git grep
使用空字节来分隔列表元素,并告诉 zsh 在空字节处分割输出。
grep_results=( ${(0)"$(git grep -lz -- TEXT_TO_SEARCH)"} )
现在您已将文件名存储在数组中,只需迭代该数组即可。
for file in $grep_results; do
print -r Opening $file
code -- $file
done
我从 VSCode 收到一条我不想要的消息,但我实际上并不理解
据猜测,code
当它注意到其标准输入是管道但在命令行上看到文件名时,会发出此消息。如果是这种情况,您可以通过运行来摆脱它code </dev/null "$file"
,这样它code
的标准输入就不是管道。