【问题标题】:How to write single-valued lines from reading a multi-valued delimited file如何从读取多值分隔文件中写入单值行
【发布时间】:2019-01-03 22:26:44
【问题描述】:

我有一个简单的问题,我相信你们中的大多数人都有答案。

我有一个带有以下数据的分隔文件:

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 脚本上创建它有什么建议吗?我尝试了嵌套的 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

请注意,角色“列”是按空格划分的(我确定这是因为 for element 语句读取了数组)

任何想法将不胜感激。

问候, 安德烈斯。

【问题讨论】:

    标签: linux bash shell csv delimiter


    【解决方案1】:

    改变

    ARRAYROLES=($f3)
    

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

    【讨论】:

    • 乔纳斯,谢谢你的回答。它适用于您的更改,而且我感到宽慰的是,至少 90% 的代码都可以。
    【解决方案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,在这种情况下消除了对额外循环的需要。

    【讨论】:

    • PesaThe,感谢您的回答。它起作用了,现在我站在我这边来理解一些语句,这段代码比我的代码紧凑得多。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-15
    • 2012-06-13
    • 2013-08-04
    • 2023-03-02
    • 1970-01-01
    • 2011-04-29
    • 1970-01-01
    相关资源
    最近更新 更多