String bash:查找字符串中的不规则值
我正在寻找字符串中匹配后的值。 假设我有两个字符串:String bash:查找字符串中的不规则值,string,bash,String,Bash,我正在寻找字符串中匹配后的值。 假设我有两个字符串: string1="Name: John Doe Age: 28 City: Oklahoma City" string2="Name: Jane Age: 29 Years City: Boston" 现在我想设置三个参数:姓名、年龄和城市。 如果我要做: name=$(echo "$string1" | awk '{ print $2 $3 }') city=$(echo "$string1" | awk '{ print $5 }')
string1="Name: John Doe Age: 28 City: Oklahoma City"
string2="Name: Jane Age: 29 Years City: Boston"
现在我想设置三个参数:姓名、年龄和城市。
如果我要做:
name=$(echo "$string1" | awk '{ print $2 $3 }')
city=$(echo "$string1" | awk '{ print $5 }')
city=$(echo "$string1" | awk '{ print $8 $9 }
它适用于string1,但显然不适用于string2。
在谷歌搜索之后,我认为我应该把它放到某种数组中,但我真的不知道如何继续
基本上,我希望Name:之后和Age:之前的所有内容都是参数$Name。年龄和城市之间的一切:成为$Age,等等
向Perl解决方案致意(部分摘自我的答案):
捕获名称:
name=`perl -ne 'print $1 if /Name: ([a-zA-Z ]+) Age:/' <<< $string`
name=`perl-ne'打印$1如果/name:([a-zA-Z]+)年龄:/”perl解决方案(部分取自我的答案):
捕获名称:
name=`perl -ne 'print $1 if /Name: ([a-zA-Z ]+) Age:/' <<< $string`
name=`perl-ne'print$1 if/name:([a-zA-Z]+)Age:/”awk
是最好的解决方案,因为您可以将字段分隔符设置为正则表达式,然后字段是$2、$3和$4
name=$(awk -F'[[:alpha:]]+: ' '{print $2}' <<<"$string1")
age=$(awk -F'[[:alpha:]]+: ' '{print $3}' <<<"$string1")
city=$(awk -F'[[:alpha:]]+: ' '{print $4}' <<<"$string1")
name=$(awk-F'[[:alpha:]+:'{print$2}'awk
是最好的解决方案,因为您可以将字段分隔符设置为正则表达式,然后字段是$2、$3和$4
name=$(awk -F'[[:alpha:]]+: ' '{print $2}' <<<"$string1")
age=$(awk -F'[[:alpha:]]+: ' '{print $3}' <<<"$string1")
city=$(awk -F'[[:alpha:]]+: ' '{print $4}' <<<"$string1")
name=$(awk-F'[[:alpha:]+:''{print$2}'需要bash版本3或更高版本:
if [[ $string1 =~ ^Name:\ (.*)\ Age:\ (.*)\ City:\ (.*) ]] ; then
name=${BASH_REMATCH[1]}
age=${BASH_REMATCH[2]}
city=${BASH_REMATCH[3]}
fi
您可能需要年龄:\([0-9]*).\City:
如果您不想将“年”包含在$Years
中,则需要bash版本3或更高版本:
if [[ $string1 =~ ^Name:\ (.*)\ Age:\ (.*)\ City:\ (.*) ]] ; then
name=${BASH_REMATCH[1]}
age=${BASH_REMATCH[2]}
city=${BASH_REMATCH[3]}
fi
您可能需要年龄:\([0-9]*).\City:
如果您不想在$Years
中包含“年”,请考虑以下命令:
name=$(awk -F": |Age" '{print $2}' <<< $string1)
age=$(awk -F": |City|Years" '{print $3}' <<< $string1)
city=$(awk -F"City: " '{print $2}' <<< $string1)
name=$(awk-F):|Age“{print$2}”考虑以下命令:
name=$(awk -F": |Age" '{print $2}' <<< $string1)
age=$(awk -F": |City|Years" '{print $3}' <<< $string1)
city=$(awk -F"City: " '{print $2}' <<< $string1)
name=$(awk-F):|Age“{print$2}”类似的东西可能会起作用:
string1="Name: John Doe Age: 28 City: Oklahoma City"
string1ByRow=$(echo "$string1" | perl -pe 's/(\w+:)/\n$1\n/g' | sed '/^$/d' | sed 's/^ *//')
string1Keys=$(echo "$string1ByRow" | grep ':$' | sed 's/:$//')
string1Vals=$(echo "$string1ByRow" | grep -v ':$')
echo "$string1Keys"
Name
Age
City
echo "$string1Vals"
John Doe
28
Oklahoma City
类似的方法可能会奏效:
string1="Name: John Doe Age: 28 City: Oklahoma City"
string1ByRow=$(echo "$string1" | perl -pe 's/(\w+:)/\n$1\n/g' | sed '/^$/d' | sed 's/^ *//')
string1Keys=$(echo "$string1ByRow" | grep ':$' | sed 's/:$//')
string1Vals=$(echo "$string1ByRow" | grep -v ':$')
echo "$string1Keys"
Name
Age
City
echo "$string1Vals"
John Doe
28
Oklahoma City
您可以使用三个perl
one行程序为变量赋值-
name=$(perl -pe 's/.*(?<=Name: )([A-Za-z ]+)(?=Age).*/\1/' file)
age=$(perl -pe 's/.*(?<=Age: )([A-Za-z0-9 ]+)(?=City).*/\1/' file)
测试文件:
[jaypal:~/Temp] cat file
string1="Name: John Doe Age: 28 City: Oklahoma City"
string2="Name: Jane Age: 29 Years City: Boston"
[jaypal:~/Temp] perl -pe 's/.*(?<=Name: )([A-Za-z ]+)(?=Age).*/\1/' file
John Doe
Jane
[jaypal:~/Temp] perl -pe 's/.*(?<=Age: )([A-Za-z0-9 ]+)(?=City).*/\1/' file
28
29 Years
[jaypal:~/Temp] perl -pe 's/.*(?<=City: )([A-Za-z ]+)"/\1/' file
Oklahoma City
Boston
名称:
[jaypal:~/Temp] cat file
string1="Name: John Doe Age: 28 City: Oklahoma City"
string2="Name: Jane Age: 29 Years City: Boston"
[jaypal:~/Temp] perl -pe 's/.*(?<=Name: )([A-Za-z ]+)(?=Age).*/\1/' file
John Doe
Jane
[jaypal:~/Temp] perl -pe 's/.*(?<=Age: )([A-Za-z0-9 ]+)(?=City).*/\1/' file
28
29 Years
[jaypal:~/Temp] perl -pe 's/.*(?<=City: )([A-Za-z ]+)"/\1/' file
Oklahoma City
Boston
城市:
[jaypal:~/Temp] cat file
string1="Name: John Doe Age: 28 City: Oklahoma City"
string2="Name: Jane Age: 29 Years City: Boston"
[jaypal:~/Temp] perl -pe 's/.*(?<=Name: )([A-Za-z ]+)(?=Age).*/\1/' file
John Doe
Jane
[jaypal:~/Temp] perl -pe 's/.*(?<=Age: )([A-Za-z0-9 ]+)(?=City).*/\1/' file
28
29 Years
[jaypal:~/Temp] perl -pe 's/.*(?<=City: )([A-Za-z ]+)"/\1/' file
Oklahoma City
Boston
[jaypal:~/Temp]perl-pe的/*(?您可以使用三个perl
一行程序为变量赋值-
name=$(perl -pe 's/.*(?<=Name: )([A-Za-z ]+)(?=Age).*/\1/' file)
age=$(perl -pe 's/.*(?<=Age: )([A-Za-z0-9 ]+)(?=City).*/\1/' file)
测试文件:
[jaypal:~/Temp] cat file
string1="Name: John Doe Age: 28 City: Oklahoma City"
string2="Name: Jane Age: 29 Years City: Boston"
[jaypal:~/Temp] perl -pe 's/.*(?<=Name: )([A-Za-z ]+)(?=Age).*/\1/' file
John Doe
Jane
[jaypal:~/Temp] perl -pe 's/.*(?<=Age: )([A-Za-z0-9 ]+)(?=City).*/\1/' file
28
29 Years
[jaypal:~/Temp] perl -pe 's/.*(?<=City: )([A-Za-z ]+)"/\1/' file
Oklahoma City
Boston
名称:
[jaypal:~/Temp] cat file
string1="Name: John Doe Age: 28 City: Oklahoma City"
string2="Name: Jane Age: 29 Years City: Boston"
[jaypal:~/Temp] perl -pe 's/.*(?<=Name: )([A-Za-z ]+)(?=Age).*/\1/' file
John Doe
Jane
[jaypal:~/Temp] perl -pe 's/.*(?<=Age: )([A-Za-z0-9 ]+)(?=City).*/\1/' file
28
29 Years
[jaypal:~/Temp] perl -pe 's/.*(?<=City: )([A-Za-z ]+)"/\1/' file
Oklahoma City
Boston
城市:
[jaypal:~/Temp] cat file
string1="Name: John Doe Age: 28 City: Oklahoma City"
string2="Name: Jane Age: 29 Years City: Boston"
[jaypal:~/Temp] perl -pe 's/.*(?<=Name: )([A-Za-z ]+)(?=Age).*/\1/' file
John Doe
Jane
[jaypal:~/Temp] perl -pe 's/.*(?<=Age: )([A-Za-z0-9 ]+)(?=City).*/\1/' file
28
29 Years
[jaypal:~/Temp] perl -pe 's/.*(?<=City: )([A-Za-z ]+)"/\1/' file
Oklahoma City
Boston
[jaypal:~/Temp]perl-pe的/*(?我提出了一个通用解决方案:
keys=() values=()
for word in $string; do
wlen=${#word}
if [[ ${word:wlen-1:wlen} = : ]]; then
keys+=("${word:0:wlen-1}") values+=("")
else
alen=${#values[@]}
values[alen-1]=${values[alen-1]:+${values[alen-1]} }$word
fi
done
我提出一个通用解决方案:
keys=() values=()
for word in $string; do
wlen=${#word}
if [[ ${word:wlen-1:wlen} = : ]]; then
keys+=("${word:0:wlen-1}") values+=("")
else
alen=${#values[@]}
values[alen-1]=${values[alen-1]:+${values[alen-1]} }$word
fi
done
bash-3.2$cat sample.log
string1="Name: John Doe Age: 28 City: Oklahoma City"
string2="Name: Jane Age: 29 Years City: Boston"
使用awk匹配内置函数:
awk ' { match($0,/Name:([A-Za-z ]*)Age:/,a); match($0,/Age:([ 0-9]*)/,b); match($0,/City:([A-Za-z ]*)/,c); print a[1]":" b[1]":"c[1] } ' sample.log
输出:
John Doe : 28 : Oklahoma City
Jane : 29 : Boston
bash-3.2$cat sample.log
string1="Name: John Doe Age: 28 City: Oklahoma City"
string2="Name: Jane Age: 29 Years City: Boston"
使用awk匹配内置函数:
awk ' { match($0,/Name:([A-Za-z ]*)Age:/,a); match($0,/Age:([ 0-9]*)/,b); match($0,/City:([A-Za-z ]*)/,c); print a[1]":" b[1]":"c[1] } ' sample.log
输出:
John Doe : 28 : Oklahoma City
Jane : 29 : Boston
很好,但它将返回age=“29年”
而不是age=“29”
@anubhava根据OP,这是正确的行为。“年龄:和城市之间的一切:成为$age”@SiegeX:谢谢你的建议。我真的很感激。很好,但它将返回age=“29年”
而不是age=“29年”
@anubhava根据OP,这是正确的行为。“年龄:和城市之间的一切:成为$Age”@SiegeX:谢谢你的建议。我真的很感激。很好,但它将返回Age=“29年”而不是Age=“29年”@choroba您应该恢复更改,根据OP,这是预期的行为。@choroba:Awesome。正如我预期的那样工作。谢谢!很好,但它将返回age=“29岁”,而不是age=“29岁”@choroba您应该恢复更改,这是OP预期的行为。@choroba:Awesome。正如我预期的那样工作。谢谢!同样的问题,它也会返回age=“29岁”,而不是age=“29”看到其他评论,我也认为OP是正确的。谢谢@EduardoIvanec的帮助。同样的问题,它也会返回age=“29岁”而不是age=“29”。看到其他评论,我也认为OP是正确的。谢谢@EduardoIvanec的帮助。这将返回age=“29岁”而不是age=“29岁”;p这是故意的,有一例年龄为29岁,另一例年龄为28岁在另一种情况下没有太多的意义。你不能对$age
变量进行任何比较。这可能是故意的,但根据给定的规范,它是不正确的。他没有说他想对$age进行数字比较。然而,他确实说出了年龄:和城市:to be$age之间的所有内容。我将把它留给OP来选择选择最佳行为(&choose the best behavior)。如果我对其进行编码,我将永远不会在我的$age
变量中获取“years”
。如果我需要打印“29 years”
我稍后会自己添加。@anubhava:谢谢你的努力。我很感激。我实际上打算保留这一切,但再次感谢你的努力。这将返回age=“29”而不是age=“29岁”;p有一次是故意的,age=“29岁”,age=“28”在另一种情况下没有太多的意义。你不能对$age
变量进行任何比较。这可能是故意的,但根据给定的规范,它是不正确的。他没有说他想对$age进行数字比较。然而,他确实说出了年龄:和城市:to be$age之间的所有内容。我将把它留给OP来选择选择最佳行为(&choose the best behavior)。如果我对其进行编码,我将永远不会在我的$age
变量中获取“years”
。如果我需要打印“29 years”
我稍后会自己附加它。@anubhava:谢谢你的努力。我很感激。我实际上打算保留这一切,但再一次。谢谢你的努力。谢谢你的建议。谢谢你的建议。请不要签署你的帖子。请参阅请不要签署你的帖子。请参阅你也可以使用awk内置FS参数并执行此操作方法也是一样。bash-3.2$awk'BEGIN{FS=“Name:| Age:| Years | Years.*City:| City:;}{if(NF>=4){Name=$2;Age=$3;City=$4;print Name:“Age:”City;}}}sample.log
输出`John Doe:28:俄克拉荷马城“Jane:29:波士顿”`您也可以使用awk内置的FS参数并以这种方式执行。bash-3.2$awk'BEGIN FS}=“姓名:|年龄:|年|年。*城市:|城市:;}{if(NF>=4){Name=$2;Age=$3;City=$4;印刷名称:”“Age:”“City;