Arrays 在另一个数组定义中重新使用数组值

Arrays 在另一个数组定义中重新使用数组值,arrays,bash,dynamic-arrays,Arrays,Bash,Dynamic Arrays,我试图在bash中使用另一个数组的值作为新数组的名称来执行数组定义,并从动态填充的另一个数组中分配数组中的值 以下是迄今为止的代码示例: adduser() { declare -i segment=$1 segment_length=${#segment[@]} for (( a = 0; a < "${segment_length}"; a++ )); do data=($(cat $filename | grep -w ${segment[a]} | awk -F

我试图在bash中使用另一个数组的值作为新数组的名称来执行数组定义,并从动态填充的另一个数组中分配数组中的值

以下是迄今为止的代码示例:

adduser() {
  declare -i segment=$1
  segment_length=${#segment[@]}
  for (( a = 0; a < "${segment_length}"; a++ )); do
    data=($(cat $filename | grep -w ${segment[a]} | awk -F ";" '{print $1}' | tr '\n' ' ' | sed 's/^/ /g'))
    ${segment[a]}=($(echo "${data[*]}"))
  done
}

cat $filename | tail -n+2 | awk -F ";" '{print $2}' | awk '{ for (i=1; i<=NF; i++) print $i }' | sed 's/\r//g' | sort -u > segments.txt
IFS=$'\r\n' GLOBIGNORE='*' command eval  'segments=($(cat segments.txt))'
for (( i = 0; i < ${#segments[@]}; i++ )); do
adduser ${segments[i]}
done
以列标题2中的值2为例。 目标是动态创建值为Value1和Value2的数组2:

2=( Value1 Value2 )
测试提供的两个答案:

我将在这里继续,因为评论太短:以下是随机文件(与示例格式相同)答案的结果:


感谢大家的参与

最后,根据我得到的简化意见,我选择了一种更简单的方法:

cat $1 | tail -n+2 | awk -F ";" '{print $2}' | awk '{ for (i=1; i<=NF; i++) print $i }' | sed 's/\r//g' | sort -u > segments.txt
IFS=$'\r\n' GLOBIGNORE='*' command eval  'segments=($(cat segments.txt))'
for (( i = 0; i < ${#segments[@]}; i++ )); do
cat $1 | grep -w ${segments[i]} | awk -F ";" '{print $1}' | tr '\n' ' ' | sed 's/^/ /g' > ${segments[i]}.txt
done
rm segments.txt

cat$1 | tail-n+2 | awk-F”“{print$2}”awk'{for(i=1;i如果我读对了,并且假设您可以在文件上没有合适的换行符,因为您显式地将它们压扁,那么这应该可以在一个
awk
调用中完成上述所有操作

awk -F'[; ]' '/;[0-9] / { for (i=2; i<=NF; i++) printf "%s ", $1 > $i".txt" }' yourInputFile
awk-F'[;]'/;[0-9]/{for(i=2;i$i.txt“}您的输入文件
所有bash都使用数组-

declare -a set=()                          # set is an array
while IFS=';' read -r key lst              # read each line into these 2 splitting on semicolons
do [[ $key =~ Header* ]] && continue       # ignore the header
   read -a val <<< "$lst"                  # split the list of values to the right of the semicolon into an array
   for e in "${val[@]}"                    # for each of those
   do  case "${set[e]:-}" in               
       *$key*) : already here, no-op   ;;  # ignore if already present
           '') set[e]="$key"           ;;  # set initial if empty
            *) set[e]="${set[e]} $key" ;;  # add delimited if new
       esac
   done
done < csv                                 # reads directly from the CSV file
在提供的测试csv内容上执行:

1: Value1
2: Value1 Value2
3: Value1
4: Value2
5: Value2
因此,
set[4]
Value2
,而
set[2]
Value1 Value2
。您可以从那里拉出它们来执行任何需要的操作

不需要cat/tail/awk/grep/tr/sed/分拣链



它还需要什么吗?

是时候切换到一种真正的编程语言了。非常有趣!请尽量提供帮助…如果你把问题归结起来,你更有可能得到帮助。我不知道第二列的
标题2
与第一列的值有什么关系。而且,
2
不是变量的有效名称ble。我不想开玩笑。每当我的shell脚本超过10行或需要实际变量和数据结构时,我都会用Perl重写它。@Socowi它不在示例文件中…它只是一个头,没有更多…2是一个示例…这显然会从文件的第二个字段生成一列唯一值,该字段您的示例是从1到5的数字,然后是从CSV返回的整字
grep
s这些数字,将第一列值放入行中每个数字的.txt文件中。我读对了吗?此逻辑将用“Value2”覆盖2.txt中的“Value1”不要同时列出它们。这是您想要的结果吗?还是您希望两者都在文件中?您的意思是让它们在一行上用空格分隔?您的意思是让这些行有换行符结尾,还是显式没有换行符?@PaulHodges column1中的值应该按集合排序。每个集合都有Column中数值的名称n2.只有第1列中的值在最终结果中才是重要的…最终会得到集合…将每个集合想象为生成的独立文件…两个集合中都有2个,并且您正在为集合中的每个数字写入一个文件,因此Value1和Value2中有一个2,但您正在执行截断写入。我将其设置为追加写入。您正在将换行符转换为空格,因此我在文件的同一行上使用空格分隔符写出了两个值。请参阅我的解决方案。如果您喜欢换行符,则很容易将每行值设为一个值。如果这不是您的意思,那么您需要更清楚地解释,并举例说明输出应该是什么。@PaulHodges我看了在这里…请看我发布的答案,因为评论太短。是的,我坚持以前的数组格式…也可以使用新行,取决于下一步如何处理集合。解决方案适用于示例,但不适用于与示例相同格式的随机输入文件。然后,您需要提供规范和e示例演示了这个问题。我们只能使用给定的内容。我的目的只是获取集合构造…理想情况下,它应该使用数组而不是文本文件来完成,并保留抽象层,但我想我需要使用bash以外的其他工具来实现这一点…抽象很好-事实上非常好-但是如果您调用
awk
在一个管道中两次,你能说明为什么不在一次调用中同时处理两个任务吗?这就像。不要添加更多的流程,让维护人员的工作变得复杂。请花一些时间来定义你的需要并解释它们。我们是来帮助你的,但我们需要数据。可以使用sed或cut代替awk的一个…可能b我应该删除所有内容(包括脚本的其余部分),只编写一个awk脚本,因为它可以用awk一行代码(非常长的一行代码)完成根据你的说法?如果有人维护它,而不是我会丢失。额外的清晰性很重要。大多数人不知道如何使用awk编码,包括我。我希望这将由不了解bash的人维护,更不用说awk了…好东西。这是我一直在寻找的…现在只需注入数据库…谢谢你r时间!当我执行它时,似乎有一个语法问题:“)语法错误:无效的算术运算符(错误标记为“1:Value1 2:Value1您可以检查它是否在执行的脚本中丢失了什么吗?脚本完全相同。我在Ubuntu 16.04 bash版本4.3.48上执行。请将此添加到您的脚本:
trap'echo“ERROR$?at$0:$LINENO-[$BASH_COMMAND]”'err
-看起来您正在尝试执行我的输出。(您可能不需要底部的打印输出。我只是为了让您看到对齐方式而将其放入其中。)您可能还需要调整变量名称。我将添加一些注释以使其更简单。
awk -F'[; ]' '/;[0-9] / { for (i=2; i<=NF; i++) printf "%s ", $1 > $i".txt" }' yourInputFile
declare -a set=()                          # set is an array
while IFS=';' read -r key lst              # read each line into these 2 splitting on semicolons
do [[ $key =~ Header* ]] && continue       # ignore the header
   read -a val <<< "$lst"                  # split the list of values to the right of the semicolon into an array
   for e in "${val[@]}"                    # for each of those
   do  case "${set[e]:-}" in               
       *$key*) : already here, no-op   ;;  # ignore if already present
           '') set[e]="$key"           ;;  # set initial if empty
            *) set[e]="${set[e]} $key" ;;  # add delimited if new
       esac
   done
done < csv                                 # reads directly from the CSV file
for n in "${!set[@]}"
do echo "$n: ${set[n]}"
done
1: Value1
2: Value1 Value2
3: Value1
4: Value2
5: Value2