如何从制表符分隔文件中截断第一个 n 和最后一个 n 列?
我尝试用这个来剪切第一个n列。但我不知道如何合并第一个和最后一个 n 列
cut -f 1-10 -d "<CTR>v <TAB>" filename
剪切可以在
-f
中取多个范围:
第 4 列及第 7 列以下:
cut -f -4,7-
或对于字段 1、2、5、6 以及从 10 开始:
cut -f 1,2,5,6,10-
等等
你问题的第一部分很简单。正如已经指出的,cut 接受省略列范围的开始或结束索引,将其解释为“从开始到列 n(包括)”或“从列 n(包括)到结束,”分别:
$ printf 'this:is:a:test' | cut -d: -f-2
this:is
$ printf 'this:is:a:test' | cut -d: -f3-
a:test
它还支持组合范围。例如,如果您想要 7 列的行中的前 3 列和最后 2 列:
$ printf 'foo:bar:baz:qux:quz:quux:quuz' | cut -d: -f-3,6-
foo:bar:baz:quux:quuz
但是,您问题的第二部分可能会有点棘手,具体取决于您期望的输入类型。如果“最后 n 列”的意思是“最后 n 列(无论它们在整行中的索引如何)”(即因为您不一定知道要提前找到多少列),那么遗憾的是,单独使用
cut
是不可能完成的。为了有效地使用cut
拉出每行中的“最后n列”,必须事先知道每行中存在的列的总数,和每行必须一致它包含的列数。
如果您不知道每行中可能存在多少个“列”(例如,因为您正在使用并非严格表格的输入),那么您将不得不使用类似
awk
之类的东西。例如,使用 awk
从每行输入中提取最后 2 个“列”(awk 将它们称为 字段, 其数量每行可能不同):
$ printf '/a\n/a/b\n/a/b/c\n/a/b/c/d\n' | awk -F/ '{print $(NF-1) FS $(NF)}'
/a
a/b
b/c
c/d
您可以使用以下方式进行剪切,
-d:分隔符,-f 表示字段
用于制表符分隔的字段
cut -d$'\t' -f 1-3,7-
使用 AWK 截断第一个和最后一个字段:
awk '{$1 = ""; $NF = ""; print}' inputfile
不幸的是,这留下了字段分隔符,所以
aaa bbb ccc
成为
[space]bbb[space]
要使用 kurumi 的答案来做到这一点,它不会留下额外的空格,而是以特定于您的要求的方式:
awk '{delim = ""; for (i=2;i<=NF-1;i++) {printf delim "%s", $i; delim = OFS}; printf "\n"}' inputfile
这也解决了该答案中的几个问题。
概括地说:
awk -v skipstart=1 -v skipend=1 '{delim = ""; for (i=skipstart+1;i<=NF-skipend;i++) {printf delim "%s", $i; delim = OFS}; printf "\n"}' inputfile
然后,您可以通过更改命令开头的变量分配来更改要在开头或结尾跳过的字段数。
您可以使用 Bash 来实现:
while read -a cols; do echo ${cols[@]:0:1} ${cols[@]:1,-1}; done < file.txt
要回答问题的第二部分,如果您有非标准的“rev”(反向)命令可用,只需反转该线,然后从第 n 列剪切到末尾,然后反向返回。例如'... |转 |切-d。 -f 2- |转速 .
因此,要结合这是问题的第一部分,您需要在第一转之前删除前“n”列。
你可以使用awk,例如,截掉第1、2和最后3列
awk '{for(i=3;i<=NF-3;i++} print $i}' file
如果您有 Ruby (1.9+) 等编程语言
$ ruby -F"\t" -ane 'print $F[2..-3].join("\t")' file
尝试以下操作:
echo a#b#c | awk -F"#" '{$1 = ""; $NF = ""; print}' OFS=""
使用
cut -b COLUMN_N_BEGINS-COLUMN_N_UNTIL INPUT.TXT > OUTPUT.TXT
如果文本文件中有“选项卡”,-f
不起作用。