Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 在bash下,如何通过解析字符串来提取两个数字_String_Bash_Numbers_Extract - Fatal编程技术网

String 在bash下,如何通过解析字符串来提取两个数字

String 在bash下,如何通过解析字符串来提取两个数字,string,bash,numbers,extract,String,Bash,Numbers,Extract,伙计们 我到处找了很多,但找不到解决问题的理想方法。所以我必须在这里发帖 我需要从一个字符串中提取两个数字,该字符串可能包含也可能不包含除我要分析的这两个数字之外的其他数字 例如,字符串可能看起来像: 新闻集L5\u snolab\u Int-300\u Exp-10000\u 3515 snolab_Int-300_Exp-10000_1185 新闻集L5\u snolab\u Int-300\u Exp-5000\u 2522 我想提取的是“Int-”和“Exp-”后面的数字,它们分别对应于

伙计们

我到处找了很多,但找不到解决问题的理想方法。所以我必须在这里发帖

我需要从一个字符串中提取两个数字,该字符串可能包含也可能不包含除我要分析的这两个数字之外的其他数字

例如,字符串可能看起来像:

新闻集L5\u snolab\u Int-300\u Exp-10000\u 3515

snolab_Int-300_Exp-10000_1185

新闻集L5\u snolab\u Int-300\u Exp-5000\u 2522

我想提取的是“Int-”和“Exp-”后面的数字,它们分别对应于第一个和第二个字符串中的300和10000,第三个字符串中的300和5000


此外,我需要使用这两个数字进行进一步分析。这就是说,我希望这两个数字可以分配给两个变量,而不是以bash脚本而不是命令行格式打印出来。

grep
可以使用这个look-behind表达式:

$ grep -Po '(?<=Int-)\d+|(?<=Exp-)\d+' file
300
10000
300
10000
300
5000
然后,只需使用
|
添加其他条件即可


使现代化 改进输出:

$ grep -Po '(?<=Int-)\d+|(?<=Exp-)\d+' file | paste - - | while read n1 n2
> do
> echo "int=$n1 ext=$n2"
> done
int=300 ext=10000
int=300 ext=10000
int=300 ext=5000

$grep-Po'(?
grep
可以通过这个look-behind表达式实现:

$ grep -Po '(?<=Int-)\d+|(?<=Exp-)\d+' file
300
10000
300
10000
300
5000
然后,只需使用
|
添加其他条件即可


使现代化 改进输出:

$ grep -Po '(?<=Int-)\d+|(?<=Exp-)\d+' file | paste - - | while read n1 n2
> do
> echo "int=$n1 ext=$n2"
> done
int=300 ext=10000
int=300 ext=10000
int=300 ext=5000

$grep-Po'(?使用bash正则表达式匹配

while read line; do
    if [[ $line =~ _Int-([[:digit:]]+)_Exp-([[:digit:]]+) ]]; then
        printf "int=%d; exp=%d\n" "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}"
    fi
done <<END
newSetupSL5_snolab_Int-300_Exp-10000_3515
snolab_Int-300_Exp-10000_1185
newSetupSL5_snolab_Int-300_Exp-5000_2522
END

删除while循环

str=newSetupSL5_snolab_Int-300_Exp-10000_3515
if [[ $line =~ _Int-([[:digit:]]+)_Exp-([[:digit:]]+) ]]; then
    printf "int=%d; exp=%d\n" "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}"
fi

使用bash正则表达式匹配

while read line; do
    if [[ $line =~ _Int-([[:digit:]]+)_Exp-([[:digit:]]+) ]]; then
        printf "int=%d; exp=%d\n" "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}"
    fi
done <<END
newSetupSL5_snolab_Int-300_Exp-10000_3515
snolab_Int-300_Exp-10000_1185
newSetupSL5_snolab_Int-300_Exp-5000_2522
END

删除while循环

str=newSetupSL5_snolab_Int-300_Exp-10000_3515
if [[ $line =~ _Int-([[:digit:]]+)_Exp-([[:digit:]]+) ]]; then
    printf "int=%d; exp=%d\n" "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}"
fi
有一种方法可以做到这一点,而不需要外部工具(叉子),如
sed
awk
或其他:

i=0;
while read string ;do
    ((i++))
    int=${string#*Int-}
    int=(${int//[a-z_-]/ })
    exp=${string#*Exp-}
    exp=(${exp//[a-z_-]/ })
    var=(${string//[a-z_-]/ })
    printf "Line #%2d contain: Int: %6s, Exp: %6s in %2d values: <%s>\n" \
        $i "$int" "$exp" ${#var[@]} "${var[*]}"
  done <<<'
newSetupSL5_snolab_Int-300_Exp-10000_3515

snolab_Int-300_Exp-10000_1185

newSetupSL5_snolab_Int-300_Exp-5000_2522
'
Line # 1 contain: Int:       , Exp:        in  0 values: <>
Line # 2 contain: Int:    300, Exp:  10000 in  4 values: <5 300 10000 3515>
Line # 3 contain: Int:       , Exp:        in  0 values: <>
Line # 4 contain: Int:    300, Exp:  10000 in  3 values: <300 10000 1185>
Line # 5 contain: Int:       , Exp:        in  0 values: <>
Line # 6 contain: Int:    300, Exp:   5000 in  4 values: <5 300 5000 2522>
Line # 7 contain: Int:       , Exp:        in  0 values: <>
i=0;
当读字符串时;做
((i++)
int=${string}*int-}
int=(${int/[a-z_-]/})
exp=${string}*exp-}
exp=(${exp/[a-z_-]/})
var=(${string/[a-z_-]/})
printf“行#%2d包含:Int:%6s,Exp:%6s,在%2d值中:\n”\
$i“$int”$exp“${var[@]}”${var[*]}”
完成在没有外部工具(叉子)要求的情况下,有办法做到这一点,如
sed
awk
或其他:

i=0;
while read string ;do
    ((i++))
    int=${string#*Int-}
    int=(${int//[a-z_-]/ })
    exp=${string#*Exp-}
    exp=(${exp//[a-z_-]/ })
    var=(${string//[a-z_-]/ })
    printf "Line #%2d contain: Int: %6s, Exp: %6s in %2d values: <%s>\n" \
        $i "$int" "$exp" ${#var[@]} "${var[*]}"
  done <<<'
newSetupSL5_snolab_Int-300_Exp-10000_3515

snolab_Int-300_Exp-10000_1185

newSetupSL5_snolab_Int-300_Exp-5000_2522
'
Line # 1 contain: Int:       , Exp:        in  0 values: <>
Line # 2 contain: Int:    300, Exp:  10000 in  4 values: <5 300 10000 3515>
Line # 3 contain: Int:       , Exp:        in  0 values: <>
Line # 4 contain: Int:    300, Exp:  10000 in  3 values: <300 10000 1185>
Line # 5 contain: Int:       , Exp:        in  0 values: <>
Line # 6 contain: Int:    300, Exp:   5000 in  4 values: <5 300 5000 2522>
Line # 7 contain: Int:       , Exp:        in  0 values: <>
i=0;
当读字符串时;做
((i++)
int=${string}*int-}
int=(${int/[a-z_-]/})
exp=${string}*exp-}
exp=(${exp/[a-z_-]/})
var=(${string/[a-z_-]/})
printf“行#%2d包含:Int:%6s,Exp:%6s,在%2d值中:\n”\
$i“$int”$exp“${var[@]}”${var[*]}”

完成并对其进行迭代:
grep-oP'(?哇,非常感谢。
粘贴---
直接进入我的备忘单,非常好!@fedorqui和glenn jackman:非常感谢你的代码-你的代码看起来非常好。但是,正如我在原始消息中提到的,我实际上需要一行代码来处理字符串,而不是一个文件。还有这行代码)应该集成到我的脚本中。你知道如何将“文件”替换为“$string”吗?非常感谢!@user2740039你可以执行类似于
$grep-Po'…”@fedorqui和glenn jackman:每次只需要解析一个字符串。但是字符串的形状是不同的。要遍历它们:
grep-oP'(?哇,非常感谢。
粘贴---
直接进入我的备忘单,非常好!@fedorqui和glenn jackman:非常感谢你的代码-你的代码看起来非常好。但是,正如我在原始消息中提到的,我实际上需要一行代码来处理字符串,而不是一个文件。还有这行代码)应该集成到我的脚本中。你知道如何用“$string”替换“file”吗?非常感谢!@user2740039您可以做一些类似于
$grep-Po'…'”@fedorqui和glenn jackman:每次只需要解析一个字符串。但是字符串的形状是不同的。谢谢您的评论!也许我在我的消息中没有说得足够清楚。事实上,每次我只需要处理一个字符串,而不是一个文件包含许多字符串。那么,您认为可以将代码从“读取行”更改为到另一个可以读取字符串的代码?非常感谢!谢谢你的评论!也许我在我的消息中没有说得足够清楚。事实上,每次我只需要处理一个字符串,而不是一个文件包含很多字符串。那么,你认为可以将代码从“读取行”更改吗另一个可以读取字符串的代码?非常感谢!非常感谢您的代码!虽然我只选择了这四行:“int=…int=…exp=…exp=…”,但它们很好地满足了我的要求。再次感谢!非常感谢您的代码!尽管我只选择了这四行:“int=…int=…exp=…exp=…”,他们很好地满足了我的要求。再次感谢!