![如何使用 bash 从字符串中选择一个部分](https://linux22.com/image/1396718/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%20bash%20%E4%BB%8E%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E9%80%89%E6%8B%A9%E4%B8%80%E4%B8%AA%E9%83%A8%E5%88%86.png)
我有一个包含字符串的数组,该字符串由以下格式的文件路径组成:
/路径/到/文件/14561234545_50303.TXT
我试图选择“1”之后但在“_”之前的部分,这样它看起来像4561234545。我一直尝试使用 sed 来执行此操作,但到目前为止还无法获得该部分。
有人能帮我举个例子说明我需要什么表达式才能拉出那部分吗?
答案1
假设您的路径存储在 bash 变量中path
,使用 bash 字符串剥离运算符剥离到最远的“/1”个字符。然后 awk 打印到 _ 字符。
回显 ${path##*/1} | awk -F_'{打印 $1}'
答案2
你可以使用 bash参数扩展对数组的所有元素:
$ paths=( /path/to/file/14561234545_50303.TXT /a/b/1ABCD_foo "/x/y/12 3 4 5_.e_f_g" )
$ new=( "${paths[@]##*/1}" )
$ new=( "${new[@]%%_*}" )
$ printf "%s\n" "${new[@]}"
4561234545
ABCD
2 3 4 5
答案3
您的问题有点不明确,但这里有一个简短的解决方案,使用sed(你说sed, 正确的? ;-))
input='/path/to/file/14561234545_50303.TXT'
section=`basename $input | sed 's/^1\([^_]\+\).*/\1/'`
解释:
- 使用以下方式获取文件名基名(我猜你只需要对文件名部分执行提取)
- 执行sed匹配如下:
^1
: 匹配1在字符串的开头(再次猜测,根据您的喜好调整)\( [^_]\+ \)
\+
:(为清晰起见添加了空格)匹配一个或多个( )字符的序列,这些字符不要匹配下划线,并将此序列保存到\1
.*
_
:匹配后面的所有内容(如果输入格式正确,则从下划线开始)
- 将匹配的文本(如果输入格式正确,则为整个字符串!)替换为步骤 2.2 中提取的非下划线字符序列
你确实需要.*
在匹配结束时包含以消耗其余的输入。如果你不这样做,步骤 3 中的替换将起作用仅有的在字符串中下划线部分,您会惊奇地发现,除了前导的 之外,输出几乎与输入相同1
。