我正在尝试使用另一个数组的值作为新数组的名称在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
目标是使用另一列中的值动态填充数组(csv的一列中的数据),然后对它们进行大量处理。
csv具有以下格式:
Header1;Header2
Value1;1 2 3
Value2;2 4 5
例如,从Header2列中获取值2。 目的是动态创建具有值Value1和Value2的数组2:
2=( Value1 Value2 )
测试提供的两个答案:
由于注释太短,我将在此处继续:这是答案的结果,其中包含一个随机文件(格式与示例相同):
ivo@spain-nuc-03:~/Downloads/TestStackoverflow$ awk -F'[; ]' '/;[0-9] / { for (i=2; i<=NF; i++) printf "%s ", $1 > $i".txt" }' real.csv
ivo@spain-nuc-03:~/Downloads/TestStackoverflow$ 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/TestStackoverflow$ ./processing.sh real.csv
ivo@spain-nuc-03:~/Downloads/TestStackoverflow$ 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/TestStackoverflow$
感谢大家的参与!
答案 0 :(得分:0)
最后,我根据要简化的注释选择了一种更简单的方法:
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
然后仅处理文件夹中其余的txt文件。
我真的很想以最初的方式完成此操作,因为它更适合于更多数据...
答案 1 :(得分:0)
如果我没看错,并且假设您明确地将它们压出后,您可以在文件上没有适当的换行符,那么应该在一次awk
调用中完成以上所有操作。
awk -F'[; ]' '/;[0-9] / { for (i=2; i<=NF; i++) printf "%s ", $1 > $i".txt" }' yourInputFile
答案 2 :(得分:0)
使用数组全扑灭-
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
这时,集合应作为空格分隔的字符串加载到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]
是Value2
,而set[2]
是Value1 Value2
。您可以从那里拉他们做任何需要的事情。
不需要cat / tail / awk / grep / tr / sed / sort链。
还需要更多吗?