
たとえば、最初の行がタイトルである入力があります。テキスト形式を下の出力に再指定できますか?
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,mo
isData
や値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