• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:シェル(bsh)でのprintfに関して)

シェル(bsh)でのprintfに関して

このQ&Aのポイント
  • シェル(bsh)で配列関数内のデータをソートして出力する方法を教えてください
  • 配列関数内のデータ数が可変であるため、ファイルに出力する際に余分なスペースが追加されてしまいます
  • スペースが入らないようにする方法や、配列関数内の数だけデータを指定する方法を教えてください

質問者が選んだベストアンサー

  • ベストアンサー
  • crossgate
  • ベストアンサー率65% (78/119)
回答No.2

>「awk」は○個目を抜き出す。程度でしか、使用したことがない為、 >NF? i++?C? みたいな感じです。 「-F' '」はデフォルトなんで省略しました。 echo "${testfile[*]}"|awk -F' ' '{for(i=1;i<=NF;i++) if(i<NF) printf("%10s ", $i); else printf("%10s\n", $i);}' なら少し分かりやすいですかね? echo "${XXX}"|awk -F' ' '{print $1}' とかなら良く使われると思うんですが、これって結局  awk -F' '   ・・・ echoの出力をスペースで区切る  '{print $1}'  ・・・ 「'{}'」の中の処理を実行する(この場合はスペースで区切った1個目を出力) ということをしてます。 なので、 echo "${testfile[*]}"|awk -F' ' '{for(i=1;i<=NF;i++) if(i<NF) printf("%10s ", $i); else printf("%10s\n", $i);}' こいつはechoの出力をスペースで区切って、「'{}'」の中の処理(ループ処理)を実行しているだけです。 ループ処理は for(i=1 ; i<=NF ; i++)   if(i<NF)     printf("%10s ", $i);   else     printf("%10s\n", $i); とインデントすると分かりやすいでしょうか? 「i++」は単にループカウンタをインクリメントしているだけです。 「NF」はawkの組み込み変数で、「処理中のレコードにいくつフィールドがあるか」を表しています。 testfile配列の要素が5個なら5ですし、10個なら10になります。 つまりこのループは、  スペースで区切ったフィールドを、1個目からフィールドの終わりまで、   最後のフィールドじゃなかったら"%10s "(最後にスペース)で、   最後のフィールドなら"%10s\n"(スペースなしで最後は改行)で出力する という処理をしています。 awkの制御構文はC言語をベースにしているので結構似ていますね。 >使用している環境はLinuxです。 その為、sh=bashとの事でしょうか。 >${testfile[*]} の様な書き方が、shでは不可ならそこから確認する必要あり! >なんですね。。 LinuxのデフォルトはBourne Shellではなくてbash(Bourne Again Shell)になります。 (cshはtcshになっていたりもするし。。。) 質問に「bsh」と書かれていたので、Bourne Shellの方だと思ってました。 LinuxにBourne Shellを入れてその上で動かしたいという訳ではないですよね? bash(Bourne Again Shell)ならOKです。 (Unix系の/bin/shはBourne Shellで、Linuxの場合は/bin/bashへのリンクなので、 Linuxでshというと実体はbashになります) 私もLinux環境(bash)で#1が動くことを確認してます。 参考までに、bashには配列がありますが、Bourne Shellには配列がありません。 evalを使って擬似的に配列を実現します。(全然配列ではないんですが。。。) 当然、evalを使う場合は echo "${testfile[*]}"|awk -F' ' '{for(i=1;i<=NF;i++) if(i<NF) printf("%10s ", $i); else printf("%10s\n", $i);}' も使えないです。 この辺りをご参考に。 http://cl.pocari.org/2003-01-29-2.html http://d.hatena.ne.jp/anmino/20091019

nagaraja
質問者

お礼

その後、この使用方法を他でも利用させて頂いております。 大変助かりました。ありがとうございました。

nagaraja
質問者

補足

crossgate 様 噛み砕いた説明ありがとうございます。 週末に時間がとれたため、再確認を行いました。 記述の仕方に関しては、まだ微妙ですが、少しづつなれて行こうと考えております。 > LinuxにBourne Shellを入れてその上で動かしたいという訳ではないですよね? 元々、スクリプトを作成する際、「sh」にて記述しようと考え行っていました。 この場合、出来るだけ「sh」として振舞うよう、エミュレートする。 的な事が記載されていた為、タイトルで「bsh」としました。 ※現に「${PIPESTATUS[@]}」等は「sh」とした時は使えなかった為。 この辺の認識も違ったようなので、これからの課題としています。 ありがとうございました。

その他の回答 (1)

  • crossgate
  • ベストアンサー率65% (78/119)
回答No.1

これってbshじゃなくてbashじゃない?とは思いますが。。。 こんな感じでどうですか。 echo "${testfile[*]}"|awk '{for(i=1;i<=NF;i++) if(i<NF) printf("%10s ", $i); else printf("%10s\n", $i);}'

nagaraja
質問者

補足

crossgate 様 返事が遅くなり申し訳ございません。 記述頂いた内容にて、行いたいことが出来ました。 ありがとうございます。 「awk」は○個目を抜き出す。程度でしか、使用したことがない為、 NF? i++?C? みたいな感じです。 なぜ成り立っているのかも微妙な為、提示頂いた記述を参考に 少し勉強したいと考えます。 使用している環境はLinuxです。 その為、sh=bashとの事でしょうか。 ${testfile[*]} の様な書き方が、shでは不可ならそこから確認する必要あり! なんですね。。 思いもつかなかった為、助かりました。 本当にありがとうございました。

関連するQ&A

専門家に質問してみよう