40

我正在尝试在 bash 中拆分制表符分隔的字段。

我知道这个答案:how to split a string in shell and get the last field

但这并不能回答制表符。

我想在制表符之前获取字符串的一部分,所以我这样做:

x=`head -1 my-file.txt`
echo ${x%\t*}

但是 \t 在字母 't' 上匹配,而不是在制表符上。做这个的最好方式是什么?

谢谢

4

7 回答 7

71

如果您的文件看起来像这样(以制表符作为分隔符):

1st-field   2nd-field

您可以cut用来提取第一个字段(默认在选项卡上操作):

$ cut -f1 input
1st-field

如果您正在使用awk,则无需使用tail获取最后一行,将输入更改为:

1:1st-field     2nd-field
2:1st-field     2nd-field
3:1st-field     2nd-field
4:1st-field     2nd-field
5:1st-field     2nd-field
6:1st-field     2nd-field
7:1st-field     2nd-field
8:1st-field     2nd-field
9:1st-field     2nd-field
10:1st-field    2nd-field

使用 awk 的解决方案:

$ awk 'END {print $1}' input
10:1st-field

纯 bash 解决方案:

#!/bin/bash

while read a b;do last=$a; done < input
echo $last

输出:

$ ./tab.sh 
10:1st-field

最后,一个解决方案使用sed

$ sed '$s/\(^[^\t]*\).*$/\1/' input
10:1st-field

这里,$是范围运算符;即只在最后一行操作。

对于您的原始问题,请使用文字标签,即

x="1st-field    2nd-field"
echo ${x%   *}

输出:

1st-field
于 2011-07-11T19:50:33.890 回答
16

在参数扩展中使用$'ANSI-C'字符串:

$ x=$'abc\tdef\tghi'
$ echo "$s"
abc     def     ghi
$ echo ">>${x%%$'\t'*}<<"
>>abc<<
于 2011-07-11T21:23:53.433 回答
9
read field1 field2 <<< ${tabDelimitedField}

或者

read field1 field2 <<< $(command_producing_tab_delimited_output)
于 2017-12-19T15:44:59.550 回答
7

使用 awk。

echo $yourfield | awk '{print $1}'

或者,在您的情况下,对于文件最后一行的第一个字段

tail yourfile | awk '{x=$1}END{print x}'
于 2011-07-11T18:45:19.420 回答
3

制表符分隔的字符串有一种简单的方法:将其转换为数组。

创建一个带制表符的字符串(在 '\t' 解释之前添加 $):

AAA=$'ABC\tDEF\tGHI'

使用括号将字符串拆分为数组:

BBB=($AAA) 

访问任何元素:

echo ${BBB[0]}
ABC
echo ${BBB[1]}
DEF
echo ${BBB[2]}
GHI
于 2019-05-24T08:03:10.843 回答
1

x=first$'\t'second
echo "${x%$'\t'*}"

引文_man bash

于 2016-08-22T23:59:53.683 回答
0

https://stackoverflow.com/users/1815797/gniourf-gniourf的答案暗示在 bash 中使用内置字段解析,但并没有真正完成答案。使用 IFS shell 参数来单独设置输入字段将完成图片,并能够在纯 bash 中解析固定数量的字段的制表符分隔的文件。

echo -e "a\tb\tc\nd\te\tf" > myfile
while IFS='<literaltab>' read f1 f2 f3;do echo "$f1 = $f2 + $f3"; done < myfile

a = b + c
d = e + f

其中,当然,被一个真正的制表符代替,而不是 \t。通常,Control-V Tab 在终端中执行此操作。

于 2021-07-08T23:49:38.750 回答