sedまたはawkを使用してテキスト形式を再指定してください。

sedまたはawkを使用してテキスト形式を再指定してください。

たとえば、最初の行がタイトルである入力があります。テキスト形式を下の出力に再指定できますか?

awk '{if ($2=="b" || $3 == "c" || $4 == "d" || $5 == "e" || $6 == "f" || $7 == "g" || $8 == "9" )'}' 

上記の試みは機能しません。私はLinuxの新しい初心者です。どんなアイデアでも大いに感謝します。

入力する:

Name    Date          Time          Mxam     Mxterm
Maxus   Date:su,mo    Time:12,3:00  mxam:20  Mxterm:10
Feros   Time:12,3:00  Mxterm:19
Michel  Mxterm:16       

希望の出力

Name    Date           Time              Mxam     Mxterm
Maxus   Date:su,mo     Time:12,3:00      mxam:20  Mxterm:10
Feros                  Time:12,3:00               Mxterm:19
Michel                                            Mxterm:16

答え1

GNUAWK:

awk -v IGNORECASE=1 '
FNR==1  {n = split($0, col)}
        {printf("%s ", $1); k=2
        for(i=2; i<=n; i++)
                printf("%s ", $0 ~ "\\<"col[i]"\\>"?$(k++):"")
        print ""}
' file | column -ts' '

IGNORECASE=1-パターンで大文字と小文字を無視
column -ts' '-入力区切り文字は空白文字であり、これはawkのプログラムを大幅に単純化します。

GNU SED:

sed -r '
s/\s+/ /g
1{h;b};G
:1;s/( \S*)(:\S*)(.*)\1/\3\1\2/i;t1
s/\n\S*//
:2;s/ [^: ]+( |$)/ \1/;t2
' file | column -ts' '

\n最初のヘッダー行は区切り文字で区切られ、各行に追加されます。最初の列を除く左側の列が右側の対応する列を置き換えます。この記号のない残りの列は空白:に置き換えられます。

sedスクリプトをデバッグするためのヒント:
-nフラグを追加sed -nrし、lコマンドを行3の終わりに置きます - 1{h;b};G;l。スクリプトを実行して4行を繰り返します。lコマンド - バッファ(パターンスペース)の内容とバッファのアンカーの終わりを表示します。$

[awk アップデート]:

awk '
NR==1   {n = split($0, col)}
        {k=1; for(i=1; i<=n; i++)
                printf( "%s ", $0 ~ "\\<"col[i]?$(k++):"")
        print ""}
' file | column -ts' '

最初のタイトルの一致には適していますが、タイトル全体(例insert_job days_somthing start_somting window term max_run_alarm must_somthing:)を作成し、単語の終わりのアンカーを使用することをお勧めします。"\\<"col[i]"\\>"

最初の列が空ではなく、一意の名前を識別子として使用する場合は、そのままにしておくことができます。

awk '
NR==1   {n = split($0, col)}
        {printf("%s ", $1); k=2
        for(i=2; i<=n; i++)
                printf("%s ", $0 ~ "\\<"col[i]?$(k++):"")
        print ""}
' file | column -ts' '

col[]- 列名col[1] == "Name"などを含む配列col[2] == "Date"。 - 単語開始アンカー。はい - 等しいcol[3] == "Time""\\<""\\<"col[2]"\\<Date"

三項演算子 -condition expression ? statement1 : statement2
条件式がtrueを返すと文1が実行され、それ以外の場合は文2が実行されます。

$0 ~ "\\<"col[i]?$(k++):""- したがって、現在の行$0にが含まれている場合は、"\\<"col[2]次のフィールドは現在の行(たとえば)$(k++)に表示される順序で印刷され、そうでない場合は空のフィールドが印刷されます。$2$0""

[awk Update2]:末尾のスペースを削除します。

awk '
NR==1   {n = split($0, col)}
        {printf("%s ", $1); k=2
        for(i=2; i<=n; i++)
            printf("%s%c", ($0~"\\<"col[i]?$(k++):""), (n>i?OFS:ORS))}
' file | column -ts' '

[awk update3]: フィールドの並べ替えに使用されます。

awk '
NR==1   {n = split($0, col)}
        {k=1; for(i=1; i<=n; i++)
                A[i] = ($0~"\\<"col[i]?$(k++):"")
        for(i in A) $i = A[i]
        }
1' file | column -ts' '

答え2

データにタグと値のペアが含まれるたびに(タグDate:su,moisDataや値isなどsu,mo)、まずマッピングを保持する配列を設定してから(tag2val[]下)、アクセス/印刷するか、これらの値ラベルを比較することができます(別名)。 。この例では、ラベルが最初の入力行に表示される順序で値を印刷しますが、このアプローチを使用すると、より多くの操作を簡単に実行できます。

$ cat tst.awk
BEGIN { OFS="\t" }
NR==1 {
    for (fldNr=1; fldNr<=NF; fldNr++) {
        val = $fldNr
        tag = tolower(val)
        tag2val[tag] = val
        tags[++numTags] = tag
    }
}
NR > 1 {
    tag2val[tags[1]] = $1
    for (fldNr=2; fldNr<=NF; fldNr++) {
        val = $fldNr
        tag = tolower(val)
        sub(/:.*/,"",tag)
        tag2val[tag] = val
    }
}
{
    for (tagNr=1; tagNr<=numTags; tagNr++) {
        tag = tags[tagNr]
        val = tag2val[tag]
        printf "%s%s", val, (tagNr<numTags ? OFS : ORS)
    }
    delete tag2val
}

$ awk -f tst.awk file | column -s$'\t' -t
Name    Date        Time          Mxam     Mxterm
Maxus   Date:su,mo  Time:12,3:00  mxam:20  Mxterm:10
Feros               Time:12,3:00           Mxterm:19
Michel                                     Mxterm:16

答え3

空間可視化sedのためのソリューションは次のとおりです。#

$ sed -E '1s/\s+/#/' file | \
  tr -s ' ' '#' | \
  sed -E '2,$s/#*(D[^#]*)*#*(T[^#]*)*#*(mx[^#]*)*#*(Mx[^#]*)*$/#\1#\2#\3#\4/' | \
  tr '#' ' ' |\
  column -nt
Name    Date        Time          Mxam     Mxterm
Maxus   Date:su,mo  Time:12,3:00  mxam:20  Mxterm:10
Feros               Time:12,3:00           Mxterm:19
Michel                                     Mxterm:16

答え4

これはデータ型を再指定する別の方法です。

私たちはawkを使ってユーティリティ用のコードを生成し、tblそれをgroffテキストプロセッサにパイプしてデータをテーブルに書きます。

< file \
awk -v OFS='@' '
{ split($0, a) }
NR==1{
  for (idx in a) b[tolower(a[idx])]=idx
  print ".TS"; print "tab(", ");"
  for (i=1; i<=NF; i++)
    printf "%s%s", "l", (i<NF ? OFS : ".")
  $1 = ORS $1
}
NR>1{
  $0=""; $1=a[1]
  for (i=2; i in a; i++) $(b[tolower(substr(a[i],1,-1+index(a[i],":")))]) = a[i]
}1
END { print ".TE" }
' | tbl | groff -Tascii | grep .

出力:

Name     Date         Time           Mxam      Mxterm
Maxus    Date:su,mo   Time:12,3:00   mxam:20   Mxterm:10
Feros                 Time:12,3:00             Mxterm:19
Michel                                         Mxterm:16

関連情報