gpt4 book ai didi

bash - 使用 Shell 脚本在 "Custom Order"中重新排列文本文件的列

转载 作者:行者123 更新时间:2023-12-04 12:24:32 25 4
gpt4 key购买 nike

我有一个名为“data.txt”的制表符分隔的文本文件,它看起来像

数据.txt

col2   col3   col4   col1
val1 val5 val9 val13
val2 val6 val10 val14
val3 val7 val11 val15
val4 val8 val12 val16
...

我有一个数组 col_order = [col1, col2, col3, col4]
目标是根据数组“col_order”中的顺序重新排列“data.txt”中的列 使用 shell 脚本 .

最终输出
col1   col2   col3   col4
val13 val1 val5 val9
val14 val2 val6 val10
val15 val3 val7 val11
val16 val4 val8 val12

我目前的进展
awk 'BEGIN{ORS=RS="\n"; S=OFS="\t"}{for (i=1; i<=NF; i++) {f[$i] = i}{ print $(f["col1"]),$(f["col2"]),$(f["col3"]),$(f["col4"])}}' data.txt> data_corrected.txt

上面的语句按预期工作,但是语句中的顺序是硬编码的,无法弄清楚如何从数组中获取顺序并将其传递到语句中。

我也愿意接受任何其他方法。

最佳答案

你可以试试下面的。

cat script.bash
List=( col1 col2 col3 col4 )
##echo ${List[*]}
awk -v bash_arr_val="${List[*]}" '
BEGIN{
num=split(bash_arr_val,array," ")
for(i=1;i<=num;i++){
array_with_bash_values_as_index[array[i]]=i
}
}

FNR==1{
for(i=1;i<=NF;i++){
if($i in array_with_bash_values_as_index){
actual_array[array_with_bash_values_as_index[$i]]=i
}
}
}
{
for(i=1;i<=num;i++){
printf("%s%s",$actual_array[i],i==NF?ORS:OFS)
}
}
' Input_file

输出如下。
col1 col2 col3 col4
val13 val1 val5 val9
val14 val2 val6 val10
val15 val3 val7 val11
val16 val4 val8 val12

Ed Morton 对变量名称建议的编辑:
$ cat tst.awk
BEGIN{
numOutFlds = split(bash_arr_val,outNr2name)
for ( outNr=1; outNr<=numOutFlds; outNr++ ) {
fldName = outNr2name[outNr]
name2outNr[fldName] = outNr
}
}

FNR==1 {
for ( inNr=1; inNr<=NF; inNr++ ) {
fldName = $inNr
outNr = name2outNr[fldName]
outNr2inNr[outNr] = inNr
}
}
{
for ( outNr=1; outNr<=numOutFlds; outNr++ ) {
inNr = outNr2inNr[outNr]
fldValue = $inNr
printf "%s%s", fldValue, (outNr<numOutFlds ? OFS : ORS)
}
}

$ awk -v bash_arr_val='col1 col2 col3 col4' -f tst.awk file
col1 col2 col3 col4
val13 val1 val5 val9
val14 val2 val6 val10
val15 val3 val7 val11
val16 val4 val8 val12

如果我只是为自己创建一个脚本而不是使用如此多的临时变量等,那么我将如何真正编写它,以使其他人尽可能清楚地理解它:
$ cat tst.awk
BEGIN{
numOutFlds = split(bash_arr_val,outNr2name)
for ( outNr=1; outNr<=numOutFlds; outNr++ ) {
name2outNr[outNr2name[outNr]] = outNr
}
}

FNR==1 {
for ( inNr=1; inNr<=NF; inNr++ ) {
f[name2outNr[$inNr]] = inNr
}
}
{
for ( outNr=1; outNr<=numOutFlds; outNr++ ) {
printf "%s%s", $(f[outNr]), (outNr<numOutFlds ? OFS : ORS)
}
}

$ awk -v bash_arr_val='col1 col2 col3 col4' -f tst.awk file
col1 col2 col3 col4
val13 val1 val5 val9
val14 val2 val6 val10
val15 val3 val7 val11
val16 val4 val8 val12

关于bash - 使用 Shell 脚本在 "Custom Order"中重新排列文本文件的列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60947762/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com