我正在尝试从基于列的“空间”调整后的文本流中提取某个(第四)字段。我试图以cut
以下方式使用命令:
cat text.txt | cut -d " " -f 4
不幸的是,cut
没有将多个空格视为一个定界符。我本来可以通过awk
awk '{ printf $4; }'
或sed
sed -E "s/[[:space:]]+/ /g"
折叠空间,但是我想知道是否有任何方法可以处理,cut
并且本机有几个定界符?
我正在尝试从基于列的“空间”调整后的文本流中提取某个(第四)字段。我试图以cut
以下方式使用命令:
cat text.txt | cut -d " " -f 4
不幸的是,cut
没有将多个空格视为一个定界符。我本来可以通过awk
awk '{ printf $4; }'
或sed
sed -E "s/[[:space:]]+/ /g"
折叠空间,但是我想知道是否有任何方法可以处理,cut
并且本机有几个定界符?
Answers:
尝试:
tr -s ' ' <text.txt | cut -d ' ' -f4
来自 tr
手册页:
-s,--squeeze-repeats替换重复字符的每个输入序列 在SET1中列出一次 该角色的
-d
并将直接从多个字符转换为制表符。例如:我到这里来是寻找一种自动导出我的显示的方法:who am i | tr -s ' ()' '\t' | cut -f5
echo "a b c" | cut -d " " -f2-
,echo "a b c" | tr -s " " | cut -d " " -f2-
在您对问题进行评论时,awk
确实是要走的路。要使用cut
是可能的共同tr -s
挤压的空间,如千电子伏的答案节目。
但是,让我为将来的读者介绍所有可能的组合。说明在“测试”部分。
tr -s ' ' < file | cut -d' ' -f4
awk '{print $4}' file
while read -r _ _ _ myfield _
do
echo "forth field: $myfield"
done < file
sed -r 's/^([^ ]*[ ]*){3}([^ ]*).*/\2/' file
给定此文件,让我们测试命令:
$ cat a
this is line 1 more text
this is line 2 more text
this is line 3 more text
this is line 4 more text
$ cut -d' ' -f4 a
is
# it does not show what we want!
$ tr -s ' ' < a | cut -d' ' -f4
1
2 # this makes it!
3
4
$
$ awk '{print $4}' a
1
2
3
4
这将顺序读取字段。通过使用,_
我们指示这是一个抛弃型变量,可以作为忽略这些字段的“垃圾变量”。这样,$myfield
无论它们之间是否有空格,我们都将其存储为文件中的第四个字段。
$ while read -r _ _ _ a _; do echo "4th field: $a"; done < a
4th field: 1
4th field: 2
4th field: 3
4th field: 4
这捕获了三组空格,没有空格([^ ]*[ ]*){3}
。然后,它捕获到到第四个字段为止的所有内容,最后用来打印\1
。
$ sed -r 's/^([^ ]*[ ]*){3}([^ ]*).*/\2/' a
1
2
3
4
awk
它不仅优雅,简单,而且还包含在tr
缺少的VMware ESXi中。
awk
!
read
如果我们不在乎它包含什么内容,也可以在单个命令中多次使用它(或者实际上是任何变量)。可以是任何东西,仅仅是它以某种方式代替了junk_var
或成为了标准whatever
:)
在对太多的限制感到沮丧之后cut
,我写了我自己的替代品,我呼吁cuts
“削减类固醇”。
cuts为解决此问题以及许多其他相关的cut / paste问题提供了最简约的解决方案。
一个例子,解决了这个特定问题:
$ cat text.txt
0 1 2 3
0 1 2 3 4
$ cuts 2 text.txt
2
2
cuts
支持:
paste
单独调用)以及更多。这些都不是标准提供的cut
。
另请参阅:https : //stackoverflow.com/a/24543231/1296044
来源和文档(免费软件):http : //arielf.github.io/cuts/