我正在尝试在bash中拆分制表符分隔字段。
我知道这个答案:how to split a string in shell and get the last field
但这并不适用于标签字符。
我想在tab字符之前获取字符串的一部分,所以我这样做:
x=`head -1 my-file.txt`
echo ${x%\t*}
但\ t匹配字母't'而不是标签上。这样做的最佳方式是什么?
由于
答案 0 :(得分:51)
如果您的文件看起来像这样(使用制表符作为分隔符):
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
Pure bash-solution:
#!/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
答案 1 :(得分:13)
在参数扩展中使用$'ANSI-C'
strings:
$ x=$'abc\tdef\tghi'
$ echo "$s"
abc def ghi
$ echo ">>${x%%$'\t'*}<<"
>>abc<<
答案 2 :(得分:6)
使用awk。
echo $yourfield | awk '{print $1}'
或者,在您的情况下,来自文件最后一行的第一个字段
tail yourfile | awk '{x=$1}END{print x}'
答案 3 :(得分:2)
read field1 field2 <<< ${tabDelimitedField}
或
read field1 field2 <<< $(command_producing_tab_delimited_output)
答案 4 :(得分:0)
x=first$'\t'second
echo "${x%$'\t'*}"
请参阅man bash
答案 5 :(得分:0)
制表符分隔的字符串有一种简单的方法:将其转换为数组。
创建带有制表符的字符串(在'\ t'解释前添加$):
AAA=$'ABC\tDEF\tGHI'
使用括号将字符串拆分为数组:
BBB=($AAA)
访问任何元素:
echo ${BBB[0]}
ABC
echo ${BBB[1]}
DEF
echo ${BBB[2]}
GHI
答案 6 :(得分: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 在终端中执行此操作。