如何在bash中拆分由制表符分隔的字符串

发布于 2024-11-19 06:48:00 字数 350 浏览 2 评论 0原文

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

我知道这个答案:如何在 shell 中分割字符串并获取最后一个字段

但这并不能回答制表符。

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

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

但是 \t 匹配字母“t”而不是制表符。最好的方法是什么?

谢谢

I'm trying to split a tab delimitted field in bash.

I am aware of this answer: how to split a string in shell and get the last field

But that does not answer for a tab character.

I want to do get the part of a string before the tab character, so I'm doing this:

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

But the \t is matching on the letter 't' and not on a tab. What is the best way to do this?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

烟酉 2024-11-26 06:48:00

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

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

If your file look something like this (with tab as separator):

1st-field   2nd-field

you can use cut to extract the first field (operates on tab by default):

$ cut -f1 input
1st-field

If you're using awk, there is no need to use tail to get the last line, changing the input to:

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

Solution using 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

outputs:

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

Lastly, a solution using sed

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

here, $ is the range operator; i.e. operate on the last line only.

For your original question, use a literal tab, i.e.

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

outputs:

1st-field
国粹 2024-11-26 06:48:00

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

$ x=
abc\tdef\tghi'
$ echo "$s"
abc     def     ghi
$ echo ">>${x%%
\t'*}<<"
>>abc<<

Use $'ANSI-C' strings in the parameter expansion:

$ x=
abc\tdef\tghi'
$ echo "$s"
abc     def     ghi
$ echo ">>${x%%
\t'*}<<"
>>abc<<
凉宸 2024-11-26 06:48:00

使用 awk。

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

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

tail yourfile | awk '{x=$1}END{print x}'

Use awk.

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

or, in your case, for the first field from the the last line of a file

tail yourfile | awk '{x=$1}END{print x}'
不寐倦长更 2024-11-26 06:48:00
read field1 field2 <<< ${tabDelimitedField}

或者

read field1 field2 <<< $(command_producing_tab_delimited_output)
read field1 field2 <<< ${tabDelimitedField}

or

read field1 field2 <<< $(command_producing_tab_delimited_output)
秋凉 2024-11-26 06:48:00

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

创建带有制表符的字符串(之前添加 $ 以进行 '\t' 解释):

AAA=

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

BBB=($AAA) 

获取对任何元素的访问权限:

echo ${BBB[0]}
ABC
echo ${BBB[1]}
DEF
echo ${BBB[2]}
GHI
ABC\tDEF\tGHI'

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

获取对任何元素的访问权限:

There is an easy way for a tab separated string : convert it to an array.

Create a string with tabs ($ added before for '\t' interpretation) :

AAA=

Split the string as an array using parenthesis :

BBB=($AAA) 

Get access to any element :

echo ${BBB[0]}
ABC
echo ${BBB[1]}
DEF
echo ${BBB[2]}
GHI
ABC\tDEF\tGHI'

Split the string as an array using parenthesis :

Get access to any element :

请别遗忘我 2024-11-26 06:48:00
x=first

请参阅 man bash 中的引用

\t'second echo "${x%

请参阅 man bash 中的引用

\t'*}"

请参阅 man bash 中的引用

x=first

See QUOTING in man bash

\t'second echo "${x%

See QUOTING in man bash

\t'*}"

See QUOTING in man bash

百思不得你姐 2024-11-26 06:48:00

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 在终端中执行此操作。

The answer from https://stackoverflow.com/users/1815797/gniourf-gniourf hints at the use of built in field parsing in bash, but does not really complete the answer. The use of the IFS shell parameter to set the input field separate will complete the picture and give the ability to parse files which are tab-delimited, of a fixed number of fields, in pure 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

Where, of course, is replaced by a real tab, not \t. Often, Control-V Tab does this in a terminal.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文