我正在尝试在bash中拆分一个制表符分隔的字段。
我知道这个答案:如何在shell中拆分字符串并获取最后一个字段
但是这并没有回答关于制表符的问题。
我想要获取制表符之前的字符串部分,所以我正在做这个:
x=`head -1 my-file.txt`
echo ${x%\t*}
但是 \t 是匹配字母 't' 而不是制表符。有什么更好的方法吗?
谢谢
我正在尝试在bash中拆分一个制表符分隔的字段。
我知道这个答案:如何在shell中拆分字符串并获取最后一个字段
但是这并没有回答关于制表符的问题。
我想要获取制表符之前的字符串部分,所以我正在做这个:
x=`head -1 my-file.txt`
echo ${x%\t*}
但是 \t 是匹配字母 't' 而不是制表符。有什么更好的方法吗?
谢谢
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 'END {print $1}' input
10:1st-field
#!/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
在参数扩展中使用$'ANSI-C'
字符串:
$ x=$'abc\tdef\tghi'
$ echo "$s"
abc def ghi
$ echo ">>${x%%$'\t'*}<<"
>>abc<<
$'\t'
在{}
参数扩展中,符合OP的要求。我使用它来加速我的脚本,比使用多个管道来cut
快76%。 - user208145echo $yourfield | awk '{print $1}'
tail yourfile | awk '{x=$1}END{print x}'
read field1 field2 <<< ${tabDelimitedField}
或者
read field1 field2 <<< $(command_producing_tab_delimited_output)
IFS=$'\t'
。 - robrecordAAA=$'ABC\tDEF\tGHI'
使用括号将字符串分割为数组:
BBB=($AAA)
获取任何元素:
echo ${BBB[0]}
ABC
echo ${BBB[1]}
DEF
echo ${BBB[2]}
GHI
AAA=$'a\t\tc'
,这将无法工作。 - jcupitt\t
。 - mateuszbx=first$'\t'second
echo "${x%$'\t'*}"
请在bash
手册中查看引用部分。
echo "${x#*$'\t'}"
。请参阅man bash
中的参数扩展。 - erwinhttps://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 键可以实现这一点。