我正在尝试从基于列的“空格”调整的文本流中提取某个(第四个)字段。我正在尝试以下列方式使用cut
命令:
cat text.txt | cut -d " " -f 4
不幸的是,cut
不会将多个空格视为一个分隔符。我本可以通过awk管道
awk '{ printf $4; }'
或sed
sed -E "s/[[:space:]]+/ /g"
要折叠空格,但我想知道是否有办法处理cut
和几个分隔符本身?
答案 0 :(得分:523)
尝试:
tr -s ' ' <text.txt | cut -d ' ' -f4
来自tr
手册页:
-s, --squeeze-repeats replace each input sequence of a repeated character that is listed in SET1 with a single occurrence of that character
答案 1 :(得分:85)
当你在问题中发表评论时,awk
真的是要走的路。与cut
一起使用tr -s
可以挤压空格,如kev's answer所示。
但是,请允许我为未来的读者介绍所有可能的组合。解释在测试部分。
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
按顺序读取字段。通过使用_
,我们指出这是一个一次性变量作为&#34;垃圾变量&#34;忽略这些字段。这样,我们将$myfield
存储为文件中的第4个字段,无论它们之间是否有空格。
$ while read -r _ _ _ a _; do echo "4th field: $a"; done < a
4th field: 1
4th field: 2
4th field: 3
4th field: 4
这会捕获三组空格,而([^ ]*[ ]*){3}
没有空格。然后,它会抓住任何到达第4个字段的空格,最后用\1
打印。
$ sed -r 's/^([^ ]*[ ]*){3}([^ ]*).*/\2/' a
1
2
3
4
答案 2 :(得分:24)
在对cut
的太多限制感到沮丧之后,我写了我自己的替代品,我打电话给cuts
以及#34;切断类固醇&#34;。
cuts提供了最简约的解决方案,以及许多其他与相关的剪切/粘贴问题。
许多人解决这个问题的一个例子:
$ 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/
答案 3 :(得分:2)
我知道cut
的版本,不,这是不可能的。 cut
主要用于解析分隔符不是空格的文件(例如/etc/passwd
)并且具有固定数量的字段。连续两个分隔符表示空字段,也适用于空格。