将字符串bash转换为带有空格和额外分隔符的数组

Mar*_*tin 5 arrays string bash delimiter

我正在尝试从包含管道("|")作为分隔符并包含空格的字符串创建数组.我一直在寻找一段时间,我已经接近了,比如像我如何在Bash中的分隔符上拆分字符串?,将字符串拆分成数组,然后更多.我很接近但不太合适.两个主要问题是字符串中有空格,有起始和结束分隔符,有些字段是空白的.此外,我不是只回显值,而是将它们分配给变量.这是源数据的格式:

|username|full name|phone1|phone2|date added|servers|comments|
Run Code Online (Sandbox Code Playgroud)

例:

|jdoe | John Doe| 555-1212 | |1/1/11 |  workstation1, server1 | added by me |
Run Code Online (Sandbox Code Playgroud)

这就是我需要的:

Username: jdoe
Fullname: John Doe
Phone1: 555-1212
Phone2: 
Date_added: 1/1/11
Servers: workstation1, server1
Comments: guest account
Run Code Online (Sandbox Code Playgroud)

编辑:我使用sed去掉每个分隔符之前和之后的第一个和最后一个分隔符和空格,现在输入:

jdoe|John Doe|555-1212||1/1/11|workstation1, server1|added by me
Run Code Online (Sandbox Code Playgroud)

这是我尝试过的事情:

oIFS="$IFS"; IFS='|'
for line in `cat $userList`; do
  arr=("$line")
  echo "Username: ${arr[0]}"  #not assigning a variable, just testing the output
  echo "Full Name: ${arr[1]}"
  echo "Phone 1: ${arr[2]}"
  echo "Phone 2: ${arr[3]}"
  # etc..
done
IFS="$oIFS"
Run Code Online (Sandbox Code Playgroud)

输出:

Username: 
Full Name: 
Phone 1:
Phone 2:
Username: jdoe
Full Name: 
Phone 1:
Phone 2:
Username: John Doe
Full Name: 
Phone 1:
Phone 2:
Run Code Online (Sandbox Code Playgroud)

我试过的另一件事:

for line in `cat $userList`; do
  arr=(${line//|/ })
  echo "Username: ${arr[0]}"
  echo "Full Name: ${arr[1]}"
  echo "Phone 1: ${arr[2]}"
  echo "Phone 2: ${arr[3]}"
  # etc
done
Run Code Online (Sandbox Code Playgroud)

输出:

Username: jdoe
Full Name: John
Phone 1:
Phone 2:
Username: Doe
Full Name: 555-1212
Phone 1:
Phone 2:
Run Code Online (Sandbox Code Playgroud)

有什么建议?谢谢!!


解决:根据下面的第一个建议,脚本现在看起来像这样:

|username|full name|phone1|phone2|date added|servers|comments|
Run Code Online (Sandbox Code Playgroud)

输出:

|jdoe | John Doe| 555-1212 | |1/1/11 |  workstation1, server1 | added by me |
Run Code Online (Sandbox Code Playgroud)

像魅力一样,非常感谢你!我没有尝试过下面的其他建议,但下次我需要做类似的事情.感谢大家!

rua*_*akh 9

你的第一次尝试非常接近.主要问题是:

  • for line in `cat $userList`拆分文件$IFS,而不是换行符.所以你应该IFS=$'\n'在循环之前和循环IFS='|'内部进行设置.(顺便说一句,值得注意的是,该for ... in `cat ...`方法读出整个文件然后将其拆分,所以如果文件可能很大,这不是最好的方法.read在这种情况下,基于A 的方法会更好.)
  • arr=("$line"),通过$line用双引号括起来,可以防止分词,因此呈现$IFS无关紧要.它应该是arr=($line).
  • 由于$line有一个领先的管道,你需要在你到达之前将其剥离arr=($line)(通过编写类似的东西$line="${line#|}"),否则你需要将其arr视为一个基于1的数组(因为${arr[0]},第一个管道之前的部分将为空) .

把它放在一起,你得到这样的东西:

oIFS="$IFS"
IFS=$'\n'
for line in `cat $userList`; do
  IFS='|'
  arr=($line)
  echo "Username: ${arr[1]}"  #not assigning a variable, just testing the output
  echo "Full Name: ${arr[2]}"
  echo "Phone 1: ${arr[3]}"
  echo "Phone 2: ${arr[4]}"
  # etc..
done
IFS="$oIFS"
Run Code Online (Sandbox Code Playgroud)

(注意:我并不担心字段的前导和尾随空格,因为"我可以单独执行该步骤"部分......或者我是否误解了这一点?您是否也需要有关该部分的帮助?)

  • OP使用`\`cat $ userList \``,但是`$(<"$ userList")`会更好. (3认同)