How to parse substrings with spaces into shell var

2019-06-10 09:13发布

What we have:

In a previous question, the following pattern was suggested to recognize lines matching a pattern in bash, and extract parts of that line into shell variables:

re='^\[([[:digit:]:]+)\] \[Server thread/INFO\]: ([^[:space:]]+) entered area ~ ([^[:space:]]+) - [(]PvP[)] ~'
line='[18:51:10] [Server thread/INFO]: Tester121 entered area ~ Wilderness - (PvP) ~'

if [[ $line =~ $re ]]; then
  time=${BASH_REMATCH[1]}
  player=${BASH_REMATCH[2]}
  area=${BASH_REMATCH[3]}
fi

However, that code doesn't work with a different where the content being matched can contain spaces. Consider the following less-simplified format:

re='???'
line='[19:27:14] [Server thread/INFO]: Tester121 entered area ~ City - Leader Tester777 - (No PvP) ~'

if [[ $line =~ $re ]]; then
  time=${BASH_REMATCH[1]}
  player=${BASH_REMATCH[2]}
  area=${BASH_REMATCH[3]}
  #leader="Tester777"
  leader=${BASH_REMATCH[4]}
  #pvp="No PvP"
  pvp=${BASH_REMATCH[5]}
fi

What should be the re for it? I am new to regex and try to learn.

标签: regex bash shell
1条回答
家丑人穷心不美
2楼-- · 2019-06-10 09:42

Since you mention "changes", I'm assuming you aren't supposed to match both cases. Correct me if I'm wrong.

So what about something like:

\[([[:digit:]:]+)\] \[Server thread/INFO\]: ([^[:space:]]+) entered area ~ ([^[:space:]]+) - Leader ([^[:space:]]+) - \(([^)]*)\) ~

You can see a live preview here.

with spaces in it

The key here is \(([^)]*)\). It matches everything within the parenthesis. This of course means that you can't have nested (close) parenthesis then.

查看更多
登录 后发表回答