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

Array values reutilization in another array definition

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

这是到目前为止的代码示例:

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

cat $filename | tail -n+2 | awk -F ";" '{print }' | 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

objective 是用另一列的值动态填充数组(csv 的一列中的数据),然后对其进行大量处理。

csv 格式如下:

Header1;Header2
Value1;1 2 3
Value2;2 4 5

以列 Header2 中的值 2 为例。 objective 是动态创建数组 2,其值为 Value1 和 Value2:

2=( Value1 Value2 )

测试提供的两个答案:

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

ivo@spain-nuc-03:~/Downloads/TestWhosebug$ awk -F'[; ]' '/;[0-9] / { for (i=2; i<=NF; i++) printf "%s ",  > $i".txt" }' real.csv 
ivo@spain-nuc-03:~/Downloads/TestWhosebug$ ll
total 68
drwxr-xr-x  2 ivo ivo  4096 Nov 27 17:16 ./
drwxr-xr-x 28 ivo ivo 32768 Nov 27 17:15 ../
-rw-rw-r--  1 ivo ivo    99 Nov 27 17:16 155.txt
-rw-rw-r--  1 ivo ivo   132 Nov 27 17:16 155?.txt
-rw-rw-r--  1 ivo ivo    99 Nov 27 17:16 2.txt
-rw-rw-r--  1 ivo ivo    66 Nov 27 17:16 2?.txt
-rw-rw-r--  1 ivo ivo   198 Nov 27 17:16 3.txt
-rw-rw-r--  1 ivo ivo    33 Nov 27 17:16 3?.txt
-rw-r--r--  1 ivo ivo  1369 Nov 27 17:14 real.csv

虽然有了上面的答案,您会得到以下信息:

ivo@spain-nuc-03:~/Downloads/TestWhosebug$ ./processing.sh real.csv

ivo@spain-nuc-03:~/Downloads/TestWhosebug$ ll
total 112
drwxr-xr-x  2 ivo ivo  4096 Nov 27 17:25 ./
drwxr-xr-x 28 ivo ivo 32768 Nov 27 17:15 ../
-rw-rw-r--  1 ivo ivo   100 Nov 27 17:25 102.txt
-rw-rw-r--  1 ivo ivo   100 Nov 27 17:25 105.txt
-rw-rw-r--  1 ivo ivo    67 Nov 27 17:25 106.txt
-rw-rw-r--  1 ivo ivo    34 Nov 27 17:25 112.txt
-rw-rw-r--  1 ivo ivo   991 Nov 27 17:25 155.txt
-rw-rw-r--  1 ivo ivo   694 Nov 27 17:25 2.txt
-rw-rw-r--  1 ivo ivo   859 Nov 27 17:25 3.txt
-rw-rw-r--  1 ivo ivo    67 Nov 27 17:25 51.txt
-rw-rw-r--  1 ivo ivo    67 Nov 27 17:25 58.txt
-rw-rw-r--  1 ivo ivo    34 Nov 27 17:25 59.txt
-rw-rw-r--  1 ivo ivo    34 Nov 27 17:25 65.txt
-rw-rw-r--  1 ivo ivo    34 Nov 27 17:25 67.txt
-rw-rw-r--  1 ivo ivo    34 Nov 27 17:25 72.txt
-rw-rw-r--  1 ivo ivo    34 Nov 27 17:25 78.txt
-rw-rw-r--  1 ivo ivo    34 Nov 27 17:25 81.txt
-rw-rw-r--  1 ivo ivo    34 Nov 27 17:25 82.txt
-rwxrwxr-x  1 ivo ivo  1180 Nov 27 17:25 processing.sh*
-rw-r--r--  1 ivo ivo  1369 Nov 27 17:14 real.csv
ivo@spain-nuc-03:~/Downloads/TestWhosebug$

感谢大家的参与!

最后我根据我得到的评论选择了一个更简单的方法来简化:

cat  | tail -n+2 | awk -F ";" '{print }' | 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  | grep -w ${segments[i]} | awk -F ";" '{print }' | tr '\n' ' ' | sed 's/^/ /g' > ${segments[i]}.txt
done
rm segments.txt

然后只处理文件夹中剩余的txt文件。

我真的很想看到这件事以我最初的方式完成,因为它更适合更多数据...

如果我没看错,并且假设你可以接受文件上没有适当的换行符,因为你明确地压缩了它们,这应该在一次 awk 调用中完成上述所有操作。

awk -F'[; ]' '/;[0-9] / { for (i=2; i<=NF; i++) printf "%s ",  > $i".txt" }' yourInputFile

全部-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

此时,集合应作为 space 分隔的字符串加载到 set[] 的每个元素中,由 csv 第二列中的行上的值索引。将它们打印出来以供验证 -

for n in "${!set[@]}"
do echo "$n: ${set[n]}"
done

在提供的测试 csv 内容上执行:

1: Value1
2: Value1 Value2
3: Value1
4: Value2
5: Value2

所以set[4]Value2set[2]Value1 Value2。你可以从那里拉他们做任何需要的事情。

不需要 cat/tail/awk/grep/tr/sed/sort 条链。

还需要更多吗?