bash 在 unix 中的字符串中第二次出现后删除所有内容

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23690698/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 10:27:27  来源:igfitidea点击:

Remove everything after 2nd occurrence in a string in unix

regexbashunixawksed

提问by Jose

I would like to remove everything after the 2nd occurrence of a particular pattern in a string. What is the best way to do it in Unix? What is most elegant and simple method to achieve this; sed, awkor just unix commands like cut?

我想在字符串中第二次出现特定模式后删除所有内容。在 Unix 中执行此操作的最佳方法是什么?实现这一目标的最优雅和最简单的方法是什么?sedawk或者只是像cut?

My input would be

我的意见是

After-u-math-how-however

Output should be

输出应该是

After-u

Everything after the 2nd -should be stripped out. The regex should also match zero occurrences of the pattern, so zero or one occurrence should be ignored and from the 2nd occurrence everything should be removed.

2nd 之后的所有东西都-应该去掉。正则表达式还应匹配模式的零次出现,因此应忽略零次或一次出现,并从第二次出现时删除所有内容。

So if the input is as follows

所以如果输入如下

After

Output should be

输出应该是

After

回答by Evan Purkhiser

Something like this would do it.

像这样的事情会做到这一点。

echo "After-u-math-how-however" | cut -f1,2 -d'-'

This will split up (cut) the string into fields, using a dash (-) as the delimiter. Once the string has been split into fields, cutwill print the 1st and 2nd fields.

这将使用破折号 ( -) 作为分隔符将字符串拆分(剪切)为字段。一旦字符串被拆分为字段,cut将打印第一个和第二个字段。

回答by potong

This might work for you (GNU sed):

这可能对你有用(GNU sed):

sed 's/-[^-]*//2g' file

回答by Ed Morton

@EvanPurkisher's cut -f1,2 -d'-'solution is IMHO the best one but since you asked about sed and awk:

@EvanPurkisher 的cut -f1,2 -d'-'解决方案恕我直言是最好的解决方案,但既然您询问了 sed 和 awk:

With GNU sed for -r

使用 GNU sed -r

$ echo "After-u-math-how-however" | sed -r 's/([^-]+-[^-]*).*//'
After-u

With GNU awk for gensub():

使用 GNU awk gensub()

$ echo "After-u-math-how-however" | awk '{
^[^-]*-\?[^-]*
=gensub(/([^-]+-[^-]*).*/,"\1","")}1' After-u

Can be done with non-GNU sed using \(and *, and with non-GNU awk using match()and substr()if necessary.

可以在非 GNU sed 中使用\(and 完成*,如果需要,可以在非 GNU awk 中使用match()and 完成substr()

回答by Steve

You could use the following regex to select what you want:

您可以使用以下正则表达式来选择您想要的:

echo "After-u-math-how-however" | grep -o "^[^-]*-\?[^-]*"

For example:

例如:

After-u

Results:

结果:

awk -F - '{print  (NF>1? FS  : "")}' <<<'After-u-math-how-however'

回答by mklement0

$ IFS=-
$ read -ra val <<< After-u-math-how-however
$ echo "${val[*]}"
After-u-math-how-however
$ echo "${val[*]:0:2}"
After-u
  • Split the line into fields based on field separator -(option spec. -F -) - accessible as special variable FSinsidethe awkprogram.
  • Always print the 1st field (print $1), followed by:
    • If there's more than 1 field(NF>1), append FS(i.e., -) and the 2nd field ($2)
    • Otherwise: append "", i.e.: effectively only print the 1st field (which in itself may be empty, if the input is empty).
  • 根据字段分隔符-(选项规范-F -)将行拆分为字段- 作为程序FS内部的特殊变量访问awk
  • 始终打印第一个字段 ( print $1),然后是:
    • 如果有超过 1 个字段( NF>1),则附加FS(即,-) 和第二个字段 ( $2)
    • 否则: append "",即:有效地只打印第一个字段(如果输入为空,它本身可能为空)。

回答by kojiro

This can be done in pure bash (which means no fork, no external process). Read into an array split on '-', then slice the array:

这可以在纯 bash 中完成(这意味着没有 fork,没有外部进程)。读入在 '-' 上拆分的数组,然后对数组进行切片:

awk '
After-u
After
= ? FS : ' FS=-

回答by Steven Penny

echo "After" | awk -F "-" '{printf "%s",; for (i=2; i<=2; i++) printf"-%s",$i}'

Result

结果

##代码##

回答by John C

This will do it in awk:

这将在 awk 中完成:

##代码##