如果我有以下字符串:
1234-56-78 17:38:00,00 [main]
我想隔离第二个',
17:38:00,00
然后解析这个词(显然是一个时间戳)来隔离17和38中的每个并将它们放到变量中,我该怎么做?在获得时间时,我尝试了以下方法:
stampLine="1234-56-78 17:38:00,00 [main]"
array=("$stampLine")
fullStamp=${array[1]}
IFS=':' read -ra splitStamp <<< $fullStamp
stampArray=($splitStamp)
x=${stampArray[0]}
echo ${x#0} # to strip leading zeroes
以及:
declare -i index
for item in $array; do
if [ index == 1 ]; then
fullStamp=$item
IFS=':' read -ra splitStamp <<< $fullStamp
stampArray=($splitStamp)
x=${stampArray[0]}
echo ${x#0} # to strip leading zeroes
fi
done
但他们两个都失败了,这让我来到这里。如果有人能够回答这个问题和/或解释我失踪的内容,我会非常感激。
答案 0 :(得分:3)
你使它变得不必要地复杂。这应该足够了:
stampLine="1234-56-78 17:38:00,00 [main]"
read date time tag <<< "${stampLine}"
IFS=: read hours minutes seconds <<< "${time}"
echo ${hours}
echo ${minutes}
当然,如果你只想一步完成,这就行了,因为IFS
是一组用于分词的字符,而不仅仅是一个字符:
IFS=" -:" read x x x hours minutes x <<< "${stampLine}"
如果你真的关心其他值,那么在它们的位置使用其他变量是必需的,但如果你不这样做,让shell重新使用“虚拟”变量是有用的......
答案 1 :(得分:1)
您第一次尝试的片段:
stampLine="1234-56-78 17:38:00,00 [main]" array=("$stampLine")
...不能做你想要的,因为你引用了$stampLine
的扩展,从而防止扩展受到分词的影响。如果删除第二行中的引号(如果$IFS
具有合适的值,例如其默认值),则$array
将初始化为三元素数组。
下面:
fullStamp=${array[1]} IFS=':' read -ra splitStamp <<< $fullStamp
...使用read
内置函数和here-string是相当重要的。我想重点是本地化$IFS
的修改值,但你可以采用其他方式。例如,您可以将原始值保存在其他变量中,然后将其还原。但就个人而言,我可能倾向于使用local
$IFS
副本声明一个函数:
split_HMS() {
local IFS=':'
splitStamp=($1)
}
# ...
fullStamp=${array[1]}
split_HMS $fullStamp
您的第二个示例遇到了额外的问题,即虽然您声明变量$index
,但您从不为其分配任何值。因此,测试[ $index == 1 ]
永远不会成功。
特别是回答您的问题,
[怎么可能]我想隔离第二个'字'[...]然后解析 这个词(显然是一个时间戳)隔离了每个17和38和 把它们变成变量[...]?
我可以用这种方式组装:
parseTime() {
local IFS=':'
local hms=($2)
hour=${hms[0]#0}
minute=${hms[1]#0}
}
stampLine="1234-56-78 17:08:00,00 [main]"
parseTime $stampLine
echo "hour: $hour"
echo "minute: $minute"
输出:
hour: 17
minute: 8
答案 2 :(得分:1)
除correct answer的twalberg之外,我建议:
stampLine="1234-56-78 17:38:00,00 [main]"
IFS=$' \n\t:' read day hre min sec foo <<<"$stampLine"
echo $day
1234-56-78
echo $hre
17
echo $min
38
echo $sec
00,00
echo $foo
[main]
当然在第二行,IFS
可能是=' :'
,但我更喜欢这样做,以避免引导可能造成的换行或不需要的标签 read
工作不对。
stampLine="1234-56-78 17:38:00,00 [main]"
read date time foo <<<$stampLine
IFS=:, read hrs min sec frac <<<$time
echo $foo
[main]
echo $time
17:38:00,00
echo $frac
00
echo $sec
00
echo $min
38
echo $hrs
17
对于这种用法,与使用read
bash 正则表达式相比,有两个成功[[ "$stampLine" =~ ... ]]
,就像在第二个示例中一样,可以更快地完成任务。
...甚至三个read
IFS=- read year month day <<<$date
的{{1}}将保持更快或减少CPU加热器然后使用 bash's正则表达式