如何通过读取多值定界文件来写入单值行

时间:2018-07-26 20:28:53

标签: linux bash shell csv delimiter

我有一个快速的问题,我相信你们中的大多数人对此都有答案。

我有一个定界文件,其中包含以下数据:

server1;user1;role
server1;user2;role,role 2
server2;user1;role,role 2,role 3

请注意,角色“列”是用逗号分隔的,并且可能具有多值信息和使用空格的名称,这与文件的其余部分以分号分隔和单值的情况不同。

我需要将每个“角色”显示在不同的行中,但与服务器和用户信息有关。例如:

server1;user1;role
server1;user2;role
server1;user2;role 2
server2;user1;role
server2;user1;role 2
server2;user1;role 3 

我不是将所有角色都放在一个服务器/用户行上,而是要求每行只有一个角色。

您是否有任何建议在Bash脚本上创建它?我尝试了嵌套边读连击,还尝试了 for 循环读取数组,但是到目前为止,我无法实现这一点(我知道可能必须使用这些功能,但以不同的方式。

这是我一直在使用的Bash脚本:

#!/bin/bash
input="/file/input.csv"
output="/file/output.csv"
declare -a ARRAYROLES
while IFS=';' read -r f1 f2 f3
do
  ARRAYROLES=($f3)
  field1=$f1
  field2=$f2
  for element in "${ARRAYROLES[@]}"
  do
    echo "$field1;$field2;$element" >> "$output"
  done
  field1=''
  field2=''
done < "$input"

这是我到目前为止的输出(非常接近,但还不够好):

server1;user1;role
server1;user2;role,role
server1;user2;2
server2;user1;role,role
server2;user1;2,role
server2;user1;3

请注意,角色'column'是按空格分隔的(我确信这是因为 for element 语句读取了数组)

任何想法都会受到赞赏。

关于, 安德烈斯。

2 个答案:

答案 0 :(得分:2)

更改

ARRAYROLES=($f3)

IFS=, read -ra ARRAYROLES <<< "$f3"

答案 1 :(得分:2)

while IFS=';' read -r server user roles; do
    IFS=',' read -r -a arr <<< "$roles"
    printf '%s\n' "${arr[@]/#/$server;$user;}"
done < "$input" > "$output"

来自help read

-a array  
     assign the words read to sequential indices of the array variable ARRAY,
     starting at zero

${arr[@]/#/...}parameter expansion,在这种情况下,不需要额外的循环。