![如何将第二列截断为给定长度](https://linux22.com/image/64805/%E5%A6%82%E4%BD%95%E5%B0%86%E7%AC%AC%E4%BA%8C%E5%88%97%E6%88%AA%E6%96%AD%E4%B8%BA%E7%BB%99%E5%AE%9A%E9%95%BF%E5%BA%A6.png)
给定表单的输入
XY981743 foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar foolkasjfdrte
如何只截断第二列?分隔符为 TAB,第二列的长度不得超过 75 个字符。
答案1
使用awk
,使用制表符分割文件并完整输出第一个字段和第二个字段的前 75 个字符(最多):
awk -F "\t" 'BEGIN { OFS=FS }; { print $1, substr($2, 1, 75); }'
正如所指出的费多尔基,您可以通过替换需要截断的字段来处理具有两个以上字段的文件:
awk -F "\t" 'BEGIN { OFS=FS }; { $2=substr($2, 1, 75); print }'
substr
如有必要,您可以通过循环将其应用于多个字段。
答案2
如果您只想打印第二列的前 75 个字符(包括空格,并假设文件中只有两列),您可以执行以下操作:
$ perl -pe 's/(\t.{75}).*/$1/' file
XY981743 foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool
或者,使用 GNU sed
:
$ sed 's/\(.*\t.\{75\}\).*/\1/' file
XY981743 foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool
或者:
$ sed -r 's/(.*\t.{75}).*/\1/' file
XY981743 foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool
或者,您可以使用fold
,告诉它剪切前 91 个字符(其中 8 个字符用于标识符,另外 8 个字符用于制表符),然后仅打印第一行:
$ fold -w 91 file | head -n1
XY981743 foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool
如果你的文件可以有超过 2 列,并且你只想截断第二列,你可以这样做(正如我刚刚注意到的,这只是对斯蒂芬的回答):
$ awk -F"\t" -vOFS="\t" '{$2=substr($2,1,75)}1;' file
XY981743 foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool
或者(请注意,如果第二列的前 75 个字符可以解释为正则表达式,则这将中断):
$ perl -F"\t" -pale 's/$F[1]/substr($F[1],0,75)/e' file
XY981743 foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool
答案3
可移植/POSIXly 具有sed
:
tab=$(printf '\t')
sed "s/\($tab[^$tab]\{0,75\}\)[^$tab]*/\1/"
或者截断每一列:
sed "s/\([^$tab]\{75\}\)[^$tab]*/\1/g"
答案4
如果有仅有的2 列:
sed -r 's/^([^\t]*\t)(.{0,75}).*/\1\2/'
{0,75}
表示从 0 到 75 个字符中选择。
.*
是超出字符 75 的删除部分。
如果有 2或者更多列:
sed -r 's/^([^\t]*\t)([^\t]{0,75})[^\t]*(.*)/\1\2\3/' file
[^\t]*
是超出字符 75 的删除部分。