【发布时间】:2013-07-12 17:06:48
【问题描述】:
我有一组数据作为输入,需要基于分隔符的倒数第二个字段。这些行可能有不同数量的分隔符。我怎样才能获得倒数第二场?
示例输入
text,blah,blaah,foo
this,is,another,text,line
预期输出
blaah
text
【问题讨论】:
我有一组数据作为输入,需要基于分隔符的倒数第二个字段。这些行可能有不同数量的分隔符。我怎样才能获得倒数第二场?
示例输入
text,blah,blaah,foo
this,is,another,text,line
预期输出
blaah
text
【问题讨论】:
从Unix cut except last two tokens 得到提示并能够找出答案:
cat datafile | rev | cut -d '/' -f 2 | rev
【讨论】:
rev 实际上可以将文件作为参数,所以这是 UUoC 案例
cat datafile | rev 没有明显优于 rev datafile
Awk 非常适合:
awk -F, '{print $(NF-1)}' file
变量 NF 是一个特殊的 awk 变量,它包含当前记录中的字段数。
【讨论】:
这里根本不需要使用cut、rev 或任何其他bash 外部工具。只需将每一行读入一个数组,然后选择你想要的部分:
while IFS=, read -r -a entries; do
printf '%s\n' "${entries[${#entries[@]} - 2]}"
done <file
在纯 bash 中执行此操作比启动管道要快得多,至少对于相当小的输入是这样。对于较大的输入,更好的工具是 awk。
【讨论】:
cuts 实用程序:$ cat file.txt
text,blah,blaah,foo
this,is,another,text,line
$ cuts -2 file.txt
blaah
text
cuts,代表“类固醇切割”:
- automatically figures out the input field separators
- supports multi-char (and regexp) separators
- automatically pastes (side-by-side) multiple columns from multiple files
- supports negative offsets (from end of line)
- has good defaults to save typing + allows the user to override them
还有更多。
在对 Unix 上的 cut 的太多限制感到沮丧之后,我写了 cuts。它旨在替换各种cut/paste 组合,从多个文件中切片和切块列,具有多种分隔符变体,同时尽量减少用户输入。
你可以从github获取cuts(免费软件,Artistic License):https://github.com/arielf/cuts/
不带参数调用cuts 将打印详细的Usage 消息。
【讨论】:
Perl 解决方案类似于来自@iiSeymour 的 awk 解决方案
perl -lane 'print $F[-2]' file
使用这些命令行选项:
n循环输入文件的每一行,不要自动打印每一行
l 在处理之前删除换行符,然后将它们添加回
a 自动拆分模式 – 将输入行拆分到 @F 数组中。默认为空格分割
e执行perl代码
@F 自动拆分数组从索引 [0] 开始,而 awk 字段以 $1 开始-1 是最后一个元素-2 是倒数第二个元素
【讨论】: