提取下划线和点之间的字符串
我有这样的字符串:
/my/directory/file1_AAA_123_k.txt
/my/directory/file2_CCC.txt
/my/directory/file2_KK_45.txt
所以基本上,下划线的数量不是固定的。我想提取第一个下划线和点之间的字符串。所以输出应该是这样的:
AAA_123_k
CCC
KK_45
我发现这个解决方案有效:
string='/my/directory/file1_AAA_123_k.txt'
tmp="${string%.*}"
echo $tmp | sed 's/^[^_:]*[_:]//'
但我想知道是否有一个更“优雅”的解决方案(例如 1 行代码)。
I have strings like these:
/my/directory/file1_AAA_123_k.txt
/my/directory/file2_CCC.txt
/my/directory/file2_KK_45.txt
So basically, the number of underscores is not fixed. I would like to extract the string between the first underscore and the dot. So the output should be something like this:
AAA_123_k
CCC
KK_45
I found this solution that works:
string='/my/directory/file1_AAA_123_k.txt'
tmp="${string%.*}"
echo $tmp | sed 's/^[^_:]*[_:]//'
But I am wondering if there is a more 'elegant' solution (e.g. 1 line code).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
使用
bash
版本 >= 3.0 和正则表达式:With
bash
version >= 3.0 and a regex:您可以使用单个
sed
命令,例如查看在线演示。 详细信息:
^
- 字符串开头.*
- 任何文本/
- a/
char[^_/]*
- 除/
和_
之外的零个或多个字符_
- a <代码>_字符\([^/]*\)
(POSIX BRE) /([^/]*)
(POSIX ERE,通过E
选项启用) - 第 1 组:除/
之外的任何零个或多个字符\.
- 点[^./]*
- 零个或多个字符除了.
和/
$
- 字符串结尾。使用
-n
,默认行输出被抑制,p
仅打印成功替换的结果。You can use a single
sed
command likeSee the online demo. Details:
^
- start of string.*
- any text/
- a/
char[^_/]*
- zero or more chars other than/
and_
_
- a_
char\([^/]*\)
(POSIX BRE) /([^/]*)
(POSIX ERE, enabled withE
option) - Group 1: any zero or more chars other than/
\.
- a dot[^./]*
- zero or more chars other than.
and/
$
- end of string.With
-n
, default line output is suppressed andp
only prints the result of successful substitution.使用 sed
Using
sed
根据您显示的示例,使用 GNU grep 您可以尝试以下代码。
说明:使用 GNU
grep
的-oP
选项分别打印精确匹配和启用 PCRE 正则表达式。在主程序中,使用正则表达式.*?_\K([^.]*)
获取第一个_
和第一次出现.
之间的值。正则表达式的解释如下:正则表达式的解释:
With your shown samples, with GNU
grep
you could try following code.Explanation: Using GNU
grep
's-oP
options here to print exact match and to enable PCRE regex respectively. In main program using regex.*?_\K([^.]*)
to get value between 1st_
and first occurrence of.
. Explanation of regex is as follows:Explanation of regex:
一个更简单的 sed 解决方案,没有任何捕获组:
A simpler
sed
solution without any capturing group:如果您需要一次处理一个文件名(例如,在 while read 循环内),您可以执行两个参数扩展,例如:
同时解析文件名列表的一个想法:
If you need to process the file names one at a time (eg, within a
while read
loop) you can perform two parameter expansions, eg:One idea to parse a list of file names at the same time:
这很简单,只是它包含开头的下划线:
This is easy, except that it includes the initial underscore: