テーブルの一部の単語をCSV形式のTXTファイルとして印刷しようとしています。
{...some code...}
number_lines=$(awk 'END { print NR }' Table1.txt
if [$number_lines -gt 5]
then
for ((i=5; i<$number_lines; i++))
do
word=$(awk 'FNR==$i {print $2}' Table1.txt)
echo $word
printf "$variable1\t$variable2\t$variable3\t$word\n" >> Table2.csv
done
fi
私はi $ 2行の単語を得ることができると思いましたが、FNR = = 5 {print $ 2}を使用して欲しいものを得ることができましたが、Table1.txtにいくつかの単語があるかどうかわからないので、何かが必要です。 from 行 5 から始まり (前の行は必要ないので) Table1.txt の行 -1 の終わりに移動します。私の貧しいコードが誰かを怒らせないことを願っています。私はこれを緊急にしなければならなかったし、以前はbashで何もしたことがなかったので申し訳ありません。
答え1
-v オプションを使用すると、シェル変数を awk 変数として非表示にできます。
awkコマンドは次のとおりです。
awk -v Seq="$i" 'FNR==Seq {print $2}' Table1.txt
その修正が提案されたら、10行すべてを単一のawkプログラムに置き換える方が速く、よりきれいになります。これにより、Table1に含まれるすべての行を読み取る必要がなくなります。 awkは行の計算とデータの読み取りに非常に堪能です。
テストされていませんが、「一部のコード」の後のすべての内容を次のように置き換えます。
awk -v Vars="${variable1}\t${variable2}\t${variable3}\t" \
'FNR >= 5 { printf ("%s\n%s%s\n", $2, Vars, $2); }' \
Table1.txt > Table2.csv
答え2
awk
ファイル全体を何度も読み取って処理するこのようなループで繰り返し実行したくありません(行数 - 4回)。
理想的には、すべての操作をawk(またはPerlやシェルではない言語)で実行する方が良いでしょう。しかし、変数に何があるのか、それとも変数がどのように定義されているのかわかりません$variable[123]
(ところで、おそらくbashでこれを行うには、次のようにする必要があります)。 、配列を使用) forループをwhile読み取りループに置き換える方法を紹介します。
while read r word ; do
echo "$word"
printf "$variable1\t$variable2\t$variable3\t$word\n" >> Table2.csv
done < <(awk 'NR > 4 {print $2}')
まだあまりありません(テキスト処理にシェル自体を使用することは決して良い考えではありません。)、しかし、少なくともawk
一度だけ実行され、入力ファイルを一度だけ読み取る。
答え3
シェルループで繰り返しawkを呼び出す代わりに、awkを一度呼び出すことでこれを行う必要があります。これは非常に遅く、しっかりとコーディングするのが難しいからです。簡潔でテスト可能なサンプル入力と期待される出力を投稿すると、さらに役立つかもしれませんが、おそらく次のようなことをしたいと思います。
awk -v vars="$variable1\t$variable2\t$variable3" '
BEGIN { OFS="\t" }
NR>5 { print vars, prev }
{ prev = $2 }
' Table1.txt > Table2.csv
たとえば、
$ variable1='this stuff'
$ variable2='other stuff'
$ variable3='last stuff'
$ cat Table1.txt
01 the foo
02 quick bar
03 brown foo
04 fox bar
05 jumped foo
06 over bar
07 the foo
08 lazy bar
09 dogs foo
10 back bar
$ awk -v vars="$variable1\t$variable2\t$variable3" '
BEGIN { OFS="\t" }
NR>5 { print vars, prev }
{ prev = $2 }
' Table1.txt > Table2.csv
$ cat Table2.csv
this stuff other stuff last stuff jumped
this stuff other stuff last stuff over
this stuff other stuff last stuff the
this stuff other stuff last stuff lazy
this stuff other stuff last stuff dogs
$variable
これらのsのいずれかに拡張したくないエスケープシーケンス(リテラルタブ文字など)を含めることができる場合は、次のように\t
します。
vars="$variable1"$'\t'"$variable2"$'\t'"$variable3" awk '
BEGIN { vars=ENVIRON["vars"]; OFS="\t" }
NR>5 { print vars, prev }
{ prev = $2 }
' Table1.txt > Table2.csv
バラよりawkスクリプトでシェル変数を使用する方法シェル変数の値を awk スクリプトに渡す方法に関する追加情報。
echo $word
シェルスクリプトでこの問題を解決してください。これがデバッグ印刷の場合、実際にはstdoutではなくstderrに移動する必要があります(つまり、で書く必要がありますecho "$word" >&2
)。その後、awkスクリプトは次のようになります。
$ awk -v vars="$variable1\t$variable2\t$variable3" '
BEGIN { OFS="\t" }
NR>5 {
print prev | "cat>&2" # or print prev > "/dev/stderr" if your awk supports that
print vars, prev
}
{ prev = $2 }
' Table1.txt > Table2.csv
しかし、本当に標準出力にエクスポートしたい場合は、次のようにすることができます。
$ awk -v vars="$variable1\t$variable2\t$variable3" '
BEGIN { OFS="\t" }
NR>5 {
print prev
print vars, prev > "Table2.csv"
}
{ prev = $2 }
' Table1.txt
または:
$ awk -v vars="$variable1\t$variable2\t$variable3" '
BEGIN { OFS="\t" }
NR>5 {
print prev
print vars, prev | "cat>&3"
}
{ prev = $2 }
' Table1.txt 3> "Table2.csv"