如何从字符串后面第n次出现后从字符串中删除字符?

时间:2016-05-18 20:35:51

标签: bash awk sed grep

所以我有这种格式的字符串:

ABC_1-23_42_4242
A_D_123_A_C_6-23_4342_2345
A_B_C_1-23_4235422_24523
A_WQERQWERB_C_1-23_48972_9792
A234234_BRWER_23423_@34234_C_5-22343_48778_4784345

我一次只使用一个字符串,所以我不必处理列表或多行,但基本上唯一重要的部分是从字符串的末尾 之后 第3个_

期望的输出:

1-23_42_4242
6-23_4342_2345
1-23_4235422_24523
1-23_48972_9792
5-22343_48778_4784345

破折号通常是一致的,但不值得信任。我能找到的最好的东西是字符串末尾的第3个_

编辑:不一定要使用sed或awk,但这些似乎就是我应该使用的。

6 个答案:

答案 0 :(得分:2)

我会使用grep

grep -Eo '([^_]+_){2}[^_]+$' file

选项:

  • -E启用扩展的POSIX正则表达式,简化了事情
  • -o仅输出匹配,而不是默认输出整行

正则表达式:

  • ([^_]+_){2}匹配一系列非_字符后跟_ - 两次
  • [^_]+与最后_
  • 之后的其余字符相匹配
  • $将前一个模式锚定到该行的末尾

输出:

1-23_42_4242
6-23_4342_2345
1-23_4235422_24523
1-23_48972_9792
5-22343_48778_4784345

答案 1 :(得分:2)

使用awk,您可以使用字段分隔符_轻松完成此操作:

awk 'BEGIN{FS=OFS="_"} NF>2{print $(NF-2), $(NF-1), $NF}' file

1-23_42_4242
6-23_4342_2345
1-23_4235422_24523
1-23_48972_9792
5-22343_48778_4784345

<强>解释

  • BEGIN{FS=OFS="_"}将输入(FS)和输出(OFS)字段分隔符设置为_
  • NF是字段数
  • $(NF-2)是最后一个字段
  • $(NF-1)是最后一个字段
  • $NF是最后一个字段

答案 2 :(得分:1)

使用GNU或OSX sed:

$ sed -E 's/.*_(([^_]+_){2}[^_]+)$/\1/' file
1-23_42_4242
6-23_4342_2345
1-23_4235422_24523
1-23_48972_9792
5-22343_48778_4784345

答案 3 :(得分:0)

可能使用的方法可能效率不高可能是计算有多少_然后搜索第(n-2)个_然后打印之后的任何内容例如在你的第一个位置 ABC_1-23_42_4242 使用计数函数计算有多少_然后搜索(n-2),因为有3 _ n = 3因此(n -2)= 1.那么然后搜索第一个_位于“3”,从0,1,2,3开始计数,然后打印从3到4之后的所有内容。

答案 4 :(得分:0)

这是另一种方法

$ rev file | cut -d_ -f1-3 | rev

1-23_42_4242
6-23_4342_2345
1-23_4235422_24523
1-23_48972_9792
5-22343_48778_4784345

答案 5 :(得分:0)

awk -F C_ '{print $2}' file

1-23_42_4242
6-23_4342_2345
1-23_4235422_24523
1-23_48972_9792
5-22343_48778_4784345