【问题标题】:How to split a string in bash delimited by tab如何在由制表符分隔的bash中拆分字符串
【发布时间】:2011-10-03 01:08:58
【问题描述】:

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

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

但这并不适用于制表符。

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

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

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

谢谢

【问题讨论】:

  • 如果您在命令行上制作方便的单行,您可以按 Ctrl+V,然后按 TAB 插入 TAB 字符。

标签: bash string-split


【解决方案1】:

使用 awk。

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

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

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

【讨论】:

  • 谢谢 - 就是这样,有一个更正:awk -F"\t" '{x=$1}END{print x}'
  • 默认 awk 字段分隔符是空格,其中包括制表符 - 但您的应用程序可能需要缩小范围。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    在参数扩展中使用$'ANSI-C' strings

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

    【讨论】:

    • 对我来说,这个解决方案在{} 参数扩展中使用$'\t',符合OP 的要求。我用它来将我的脚本加速 76%,而不是使用多个管道到 cut
    【解决方案4】:

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

    参见man bash中的报价

    【讨论】:

      【解决方案5】:
      read field1 field2 <<< ${tabDelimitedField}
      

      read field1 field2 <<< $(command_producing_tab_delimited_output)
      

      【讨论】:

      • 请用一些解释来扩充您的纯代码答案,以减少 StackOverflow 是免费代码编写服务的印象。
      【解决方案6】:

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

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

      AAA=$'ABC\tDEF\tGHI'
      

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

      BBB=($AAA) 
      

      访问任何元素:

      echo ${BBB[0]}
      ABC
      echo ${BBB[1]}
      DEF
      echo ${BBB[2]}
      GHI
      

      【讨论】:

      • 不幸的是,如果项目可以是零长度字符串,例如AAA=$'a\t\tc',这将不起作用
      • 确实是个坏消息! :-( 感谢您的通知。但到目前为止,我很幸运,它适用于我的脚本。
      【解决方案7】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-29
        • 2014-02-19
        • 1970-01-01
        • 2017-04-02
        • 2018-01-19
        • 1970-01-01
        • 2017-08-21
        • 1970-01-01
        相关资源
        最近更新 更多