bash:获得第n列输出的最短途径
比方说,在你的工作date间,你反复遇到以下forms的列表输出(在我的Rails工作目录中执行svn st
):
? changes.patch M app/models/superman.rb A app/models/superwoman.rb
为了处理命令的输出 – 在这种情况下是文件名 – 需要进行某种parsing,以便第二列可以用作下一个命令的input。
我一直在做的是使用awk
来获得第二列,例如当我想删除所有文件(不是那是一个典型的用例:),我会这样做:
svn st | awk '{print $2}' | xargs rm
由于我input了很多,所以一个自然的问题是:在bash中是否有一个更短的(因此更酷)的方式来完成这个任务?
注:我所要求的实质上是一个shell命令的问题,即使我的具体例子是在我的svn工作stream程。 如果你觉得工作stream是愚蠢的,并build议一种替代方法,我可能不会投票给你,但其他人可能,因为这里的问题是真正如何获得第b列中的第n列命令输出,以尽可能最短的方式。 谢谢 :)
您可以使用cut
来访问第二个字段:
cut -f2
编辑:对不起,没有意识到SVN在其输出中不使用制表符,所以这是没有用的。 你可以裁剪输出,但有点脆弱 – 像cut -c 10-
这样的东西可以工作,但确切的价值取决于你的设置。
另一个选项是这样的: sed 's/.\s\+//'
要完成同样的事情:
svn st | awk '{print $2}' | xargs rm
只使用bash你可以使用:
svn st | while read ab; do rm "$b"; done
当然,这并不短,但是效率更高一些,它可以正确处理文件名中的空格。
试试zsh。 它支持后缀别名,所以你可以在你的.zshrc中定义X.
alias -g X="| cut -d' ' -f2"
那么你可以这样做:
猫文件X
您可以进一步将其定义为第n列:
alias -g X2="| cut -d' ' -f2" alias -g X1="| cut -d' ' -f1" alias -g X3="| cut -d' ' -f3"
这将输出文件“文件”的第n列。 你可以这样做,grep输出或更less的输出。 这非常方便,是zsh的杀手锏。
您可以进一步将D定义为别名-g D =“| xargs rm”
现在你可以input猫文件X1 D
删除文件“file”第一列中提到的所有文件。
如果你知道这个bash,除了一些新的function,zsh并不是什么大的变化。
HTH克里斯
我发现自己在相同的情况下,最终将这些别名添加到我的.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}'"
这允许我写这样的事情:
svn st | c2 | xargs rm
看起来你已经有了一个解决scheme。 为了使事情变得简单,为什么不把命令放在一个bash脚本(简称)中,而只是运行它,而不是每次input“long”命令?
因为你似乎不熟悉脚本,这里是一个例子。
#!/bin/sh # usage: svn st | x 2 | xargs rm col=$1 shift awk -v col="$col" '{print $col}' "${@--}"
如果将其保存在~/bin/x
,并确保~/bin
在你的PATH
(现在你可以并且应该把它放在你的.bashrc
),你可以使用最短的命令来提取列n; x n。
脚本应该做适当的错误检查和保释,如果调用一个非数字参数或不正确的参数数量等。 但在这个基本版本上的扩展将在102单元。
也许你会想扩展脚本来允许不同的列分隔符。 Awk默认分析input到空白字段; 要使用不同的分隔符,请使用-F ':'
其中:
是新的分隔符。 实现这个作为脚本的一个选项使它稍长一点,所以我把它作为读者的一个练习。
用法
给定一个文件file
:
1 2 3 4 5 6
你可以通过标准input(使用无用的cat
只是作为一个更有用的东西占位符);
$ cat file | sh script.sh 2 2 5
或将其作为脚本的参数提供:
$ sh script.sh 2 file 2 5
在这里, sh script.sh
假设脚本被保存为当前目录下的script.sh
; 如果你在PATH
某个地方用一个更有用的名字来保存它,并且把它标记为可执行的,就像上面的说明一样,显然使用这个有用的名字(而不是sh
)。
请注意,该文件path不必在svn st输出的第二列。 例如,如果您修改文件,并修改它的属性,它将是第3列。
查看可能的输出示例:
svn help st
示例输出:
M wc/bar.c A + wc/qax.c
我build议削减前8个字符:
svn st | cut -c8- | while read FILE; do echo whatever with "$FILE"; done
如果你想100%确定,例如最后用空格处理花哨的文件名,你需要parsingxml输出:
svn st --xml | grep -o 'path=".*"' | sed 's/^path="//; s/"$//'
当然,你可能想使用一些真正的XMLparsing器而不是grep / sed。
如果您可以手动select列,那么使用pick可以非常快速:
svn st | pick | xargs rm
只要去第二列的任何单元格,按c
,然后按enter