【发布时间】:2010-11-04 17:41:39
【问题描述】:
我正在考虑使用 find 或 grep 来收集文件,也许可以使用 sed 来进行更改,但是如何处理输出?还是在vim中使用“argdo”会更好?
注意:这个问题要求的是命令行解决方案,而不是 IDE。建议 IDE 的答案和 cmets 将被冷静、礼貌和平静地标记出来。 :-)
【问题讨论】:
标签: bash vim command-line refactoring sed
我正在考虑使用 find 或 grep 来收集文件,也许可以使用 sed 来进行更改,但是如何处理输出?还是在vim中使用“argdo”会更好?
注意:这个问题要求的是命令行解决方案,而不是 IDE。建议 IDE 的答案和 cmets 将被冷静、礼貌和平静地标记出来。 :-)
【问题讨论】:
标签: bash vim command-line refactoring sed
我实际上已经开始在 vim 中使用“argdo”了。首先,设置参数:
:args **/*.java
“**”遍历所有子目录,“args”将它们设置为 arg 列表(就好像您启动 vim 时将所有这些文件作为 vim 的参数一样,例如:vim package1/One.java package1 /Two.java package2/One.java)
然后摆弄我需要的任何命令来进行我想要的转换,例如:
:/^package.*$/s/$/\rimport package.name.*;/
“/^package.*$/”作为其后普通“s///”替换的地址; "/$/" 匹配包行的结尾; "\r" 是换行符。
现在我可以使用 argdo 对所有文件自动执行此操作。我点击“:”,然后向上箭头得到上面的行,然后插入“argdo”,这样它就变成了:
:argdo /^package.*$/s/$/\rimport package.name.*;/
此“argdo”将该转换应用于参数列表中的每个文件。
这个解决方案的真正好处在于它并不危险:它实际上还没有更改文件,但我可以查看它们以确认它是否符合我的要求。我可以撤消特定文件,或者如果我不喜欢它所做的事情,我可以退出(顺便说一句:我已将 ^n 和 ^p 映射到 :n 和 :N 以便我可以快速浏览文件)。现在,我用 ":wa" - "write all" 文件提交它们。
:wa
此时,我仍然可以撤消特定文件,或根据需要对它们进行微调。
同样的方法可用于其他重构(例如,在许多文件中更改方法签名并调用它)。
顺便说一句:这很笨拙:“s/$/\rtext/”...必须有更好的方法从 vim 的命令行附加文本...
【讨论】:
您也可以使用 ed 命令进行文件内搜索和替换:
# delete all lines matching foobar
ed -s test.txt <<< $'g/foobar/d\nw'
【讨论】:
for i in `ls *java`
do
sed -i '.old' '1 i\
Your include statement here.
' $i
done
应该这样做。 -i 进行就地替换, .old 保存旧文件以防万一出现问题。根据需要替换迭代器 *java(可能是 'find . | grep java' 或其他东西。)
【讨论】:
我是以下的忠实粉丝
export MYLIST=`find . -type f -name *.java`
for a in $MYLIST; do
mv $a $a.orig
echo "import.stuff" >> $a
cat $a.orig >> $a
chmod 755 $a
done;
mv 是邪恶的,最终会得到你。但我在很多事情上都使用了同样的结构,它是我选择的实用刀。
更新:此方法还备份您应该使用任何方法执行的文件。此外,它只使用 shell 的功能。您不必记忆您不经常使用的工具。教一只猴子(相信我我已经做到了)很简单。而且您通常足够明智地将它扔掉,因为它花了四秒钟的时间来写。
【讨论】:
您可以使用sed 在文件的第一行之前插入一行:
sed -ie "1i import package.name.*;" YourClass.java
使用 for 循环遍历所有文件并在它们上运行此表达式。但是如果你有包要小心,因为import 语句必须在包声明之后。如果是这种情况,您可以使用更复杂的 sed 表达式。
【讨论】:
如果有一种体面的方法可以“仅对第一行执行此操作”,我会使用 sed,但我不知道有哪一种方法是我想不到的。为什么不改用 perl。比如:
find . -name '*.java' -exec perl -p -i.bak -e '
BEGIN {
print "import package.name.*;\n"
}' {} \;
应该做的工作。更多详情请查看perlrun(1)。
【讨论】:
我建议sed -i 避免担心输出的需要。由于您没有指定您的平台,请检查您的手册页; sed -i 的语义因 Linux 和 BSD 而异。
【讨论】: