结果

结果

我需要将一些数据转换为作业。我很确定对于 awk 来说这看起来是一项非常简单的工作,但我对此感到非常不舒服。

每个数据元素(和列)均以制表符分隔。数据元素可以包含空格和特殊字符,但不能包含制表符。

输入示例:

column1 column2 column3
rowA1   rowA2   rowA3
rowB1   rowB2   rowB3

预期输出:

column1 = rowA1
column2 = rowA2
column3 = rowA3

column1 = rowB1
column2 = rowB2
column3 = rowB3

(行数任意,不超过数百行)

有任何线索如何做到这一点吗? (使用 awk 或 Linux 上的任何标准命令行工具)

答案1

例如:

{
    if (NR==1){
        for (i=1; i<=NF; ++i){
            arr[i] = $i
        }
    }else{
        for (i=1; i<=NF; ++i){
            print(arr[i]," = ",$i)
        }
    }
    print("")
}

跑步:

awk -f script.awk input

答案2

cat data |
while IFS=$'\t' read -r -a a; do
   case ${flag+'set'} in
      "set" )
         set -- "${a[@]}"
         for c in "${C[@]}"; do echo "$c = $1"; shift; done
         echo ;;

      * ) C=( "${a[@]}" ); flag= ;;
   esac
done

sed -Ee '
   1h;1N
   /^\n$/{
      $d;P;g;N
   }
   s/^(\S+)\s*((\S.*)?)\n(\S+)\s*((\S.*)?)/\1 = \4\n\2\n\5/
   P;D
' data

perl -F'\t+' -lane '
   @C or @C = @F,next;
   print "$C[$_] = $F[$_]" for 0 .. $#C;
   eof or print q[];
' data

结果

column1 = rowA1
column2 = rowA2
column3 = rowA3

column1 = rowB1
column2 = rowB2
column3 = rowB3

解释

  1. bash

    C*)在标志未设置期间将第一行存储在数组中。然后赶紧设置一下,免得下次以后我们就不会到这里了。 *) 使用命令将数组a分成参数set。 *) 然后我们循环遍历列,通过循环中的“${c[@]}”访问for并与 $1 一起打印(然后移出) *) 注意 IFS 通过构造设置为制表符$'\t'。由于它是特殊字符之一,因此一系列这些字符将被折叠为一个,因此我们不会看到空字段。

  2. perl

    *) 将 FS 设置为一个或多个 TAB:-F'\t+'并打开自动分割模式。 *)与bash基于解决方案的逻辑相同,其中我们将第一行中找到的列数据存储在@C数组中。打印数组@C和当前记录字段数据,@F各取一个。

  3. sed

    *) 这里我们首先将所有制表符转换为空格。 *) 将第一行列数据存储在保留空间中。 *) 对于所有其他行,将列附加到当前行。 *)然后我们继续从当前行/列中选取第一个元素,并通过去掉这些打印的内容来缩小模式空间。 *) 当没有剩余空格时发生停止条件。

相关内容