假设您在工作日期间反复遇到bash中某些命令的以下形式的列化输出(在我的情况下,svn st
在我的Rails工作目录中执行):
? changes.patch
M app/models/superman.rb
A app/models/superwoman.rb
Run Code Online (Sandbox Code Playgroud)
为了使用命令的输出 - 在这种情况下是文件名 - 需要某种解析,以便第二列可以用作下一个命令的输入.
我一直在做的是用来awk
获取第二列,例如当我想删除所有文件(不是那个典型的用例:)时,我会这样做:
svn st | awk '{print $2}' | xargs rm
Run Code Online (Sandbox Code Playgroud)
由于我输入了很多,一个自然的问题是:在bash中有没有更短(更酷)的方法来实现这一点?
注意:我所要求的实际上是一个shell命令问题,即使我的具体示例是在我的svn工作流程上.如果您认为工作流程很愚蠢并建议另一种方法,我可能不会投票给您,但其他人可能会,因为这里的问题实际上是如何以最短的方式获得bash中的第n列命令输出.谢谢 :)
por*_*ges 104
您可以使用cut
访问第二个字段:
cut -f2
Run Code Online (Sandbox Code Playgroud)
编辑:对不起,没有意识到SVN在其输出中没有使用制表符,所以这有点无用.你可以定制cut
输出,但它有点脆弱 - 类似的cut -c 10-
工作,但确切的值将取决于你的设置.
另一种选择是: sed 's/.\s\+//'
Ric*_*key 91
完成同样的事情:
svn st | awk '{print $2}' | xargs rm
Run Code Online (Sandbox Code Playgroud)
只使用bash你可以使用:
svn st | while read a b; do rm "$b"; done
Run Code Online (Sandbox Code Playgroud)
当然,它并不短,但效率更高,它可以正确处理文件名中的空白.
Sta*_*ked 30
我发现自己处于相同的情况,最后将这些别名添加到我的.profile
文件中:
alias c1="awk '{print \$1}'"
alias c2="awk '{print \$2}'"
alias c3="awk '{print \$3}'"
alias c4="awk '{print \$4}'"
alias c5="awk '{print \$5}'"
alias c6="awk '{print \$6}'"
alias c7="awk '{print \$7}'"
alias c8="awk '{print \$8}'"
alias c9="awk '{print \$9}'"
Run Code Online (Sandbox Code Playgroud)
这允许我写这样的事情:
svn st | c2 | xargs rm
Run Code Online (Sandbox Code Playgroud)
Chr*_*ris 15
试试zsh.它支持后缀别名,因此您可以在.zshrc中定义X.
alias -g X="| cut -d' ' -f2"
Run Code Online (Sandbox Code Playgroud)
然后你可以这样做:
cat file X
Run Code Online (Sandbox Code Playgroud)
您可以更进一步,为第n列定义它:
alias -g X2="| cut -d' ' -f2"
alias -g X1="| cut -d' ' -f1"
alias -g X3="| cut -d' ' -f3"
Run Code Online (Sandbox Code Playgroud)
这将输出文件"file"的第n列.您也可以为grep输出或更少的输出执行此操作.这非常方便,是zsh的杀手级功能.
您可以更进一步,将D定义为:
alias -g D="|xargs rm"
Run Code Online (Sandbox Code Playgroud)
现在你可以输入:
cat file X1 D
Run Code Online (Sandbox Code Playgroud)
删除文件"file"第一列中提到的所有文件.
如果您知道bash,除了一些新功能之外,zsh并没有太大的变化.
HTH Chris
因为您似乎不熟悉脚本,所以这是一个例子.
#!/bin/sh
# usage: svn st | x 2 | xargs rm
col=$1
shift
awk -v col="$col" '{print $col}' "${@--}"
Run Code Online (Sandbox Code Playgroud)
如果你保存它~/bin/x
并确保~/bin
在你的PATH
(现在这是你可以并且应该放在你的东西中.bashrc
)你有一个最短的命令通常提取列n; x
如果使用非数字参数或不正确数量的参数调用等,脚本应该进行适当的错误检查和保释; 但扩展这个基本的必备版本将在102单元.
也许您会希望扩展脚本以允许不同的列分隔符.默认情况下,awk将输入解析为空格上的字段; 使用不同的分隔符,使用-F ':'
这里:
是新的分隔符.将此作为脚本的一个选项实现使它稍微长一些,所以我将其留作读者练习.
给定一个文件file
:
1 2 3
4 5 6
Run Code Online (Sandbox Code Playgroud)
你可以通过stdin传递它(仅使用一个无用cat
的占位符来获得更有用的东西);
$ cat file | sh script.sh 2
2
5
Run Code Online (Sandbox Code Playgroud)
或者将其作为脚本的参数提供:
$ sh script.sh 2 file
2
5
Run Code Online (Sandbox Code Playgroud)
这里sh script.sh
假设脚本保存script.sh
在当前目录中; 如果你在你的某个地方用一个更有用的名字保存它并将其PATH
标记为可执行文件,就像上面的说明一样,显然使用有用的名称(而不是sh
).
看来您已经有了解决方案。为了使事情变得容易,为什么不将命令放在bash脚本(具有短名称)中,然后直接运行而不是每次都键入“ long”命令呢?