如何通过读取多值分隔文件写入单值行
How to write single-valued lines from reading a multi-valued delimited file
我有一个简短的问题,我相信你们中的大多数人都能找到答案。
我有一个包含以下数据的分隔文件:
server1;user1;role
server1;user2;role,role 2
server2;user1;role,role 2,role 3
请注意,角色 'column' 是逗号分隔的,并且可能包含多值信息和使用空格的名称,这与文件的其余部分是分号分隔的单值不同。
我需要把每个'role'显示成不同的行,但是涉及到服务器和用户信息。例如:
server1;user1;role
server1;user2;role
server1;user2;role 2
server2;user1;role
server2;user1;role 2
server2;user1;role 3
我要求每行一个角色,而不是将所有角色都放在一行 server/user 上。
您对在 Bash 脚本上创建它有什么建议吗?我尝试了嵌套的 while read 组合,以及 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 语句读取数组)
任何想法将不胜感激。
此致,
安德烈斯
改变
ARRAYROLES=($f3)
至
IFS=, read -ra ARRAYROLES <<< "$f3"
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,在这种情况下消除了额外循环的需要。
我有一个简短的问题,我相信你们中的大多数人都能找到答案。
我有一个包含以下数据的分隔文件:
server1;user1;role
server1;user2;role,role 2
server2;user1;role,role 2,role 3
请注意,角色 'column' 是逗号分隔的,并且可能包含多值信息和使用空格的名称,这与文件的其余部分是分号分隔的单值不同。
我需要把每个'role'显示成不同的行,但是涉及到服务器和用户信息。例如:
server1;user1;role
server1;user2;role
server1;user2;role 2
server2;user1;role
server2;user1;role 2
server2;user1;role 3
我要求每行一个角色,而不是将所有角色都放在一行 server/user 上。
您对在 Bash 脚本上创建它有什么建议吗?我尝试了嵌套的 while read 组合,以及 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 语句读取数组)
任何想法将不胜感激。
此致, 安德烈斯
改变
ARRAYROLES=($f3)
至
IFS=, read -ra ARRAYROLES <<< "$f3"
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,在这种情况下消除了额外循环的需要。