web-dev-qa-db-ja.com

POSIXシェルで文字を繰り返す方法に関する説明が必要

スタックオーバーフローに関する次の回答、

bashで文字を繰り返すにはどうすればよいですか?

次のように、[〜#〜] posix [〜#〜]のように単一の文字を繰り返す1つのもっともらしい方法を課します。この例では、等号を100回使用します。

printf %100s | tr " " "="

私の問題は、それがどのように機能するのか理解していないことです。 マニュアルを読むのようなコメントはご遠慮ください、私はそうしました、そして私はそれから利口ではないので、trを使用したことがなく、そのようなものを見たことがないので、この質問をしますprintfステートメント。

8

つまり、printf %100sは100個のスペースを印刷し、tr " " "="はそれらのスペースを等号に変換して、100個の等号を効果的に印刷します。

それを分解する:


printfはシェルの組み込みです。通常は2つ以上の引数を受け取ります。最初の引数は「フォーマット文字列」で、残りはそのフォーマット文字列のプレースホルダーを埋めるために使用されます。テンプレートが完全に入力されると、結果が出力されます。引数が残っている場合は、最初からやり直して、さらに引数を入力し、結果の文字列を出力します。

printfに使用されるフォーマット文字列は、%で始まり1文字で終わるフォーマット指定をとるため、%dは整数を意味します(10進数を使用するため、「d」を使用) 、%fは浮動小数点数を意味し、%sは文字列を意味します。 %の後の文字以外の文字は、フォーマット指定の修飾子であり、特に数値は、出力時にフィールドの要求された長さを指定するために使用されます。したがって、%100sは、文字列を100文字以上にフォーマットし、スペースを埋めて、正しい位置に保ちます(つまり、文字列の先頭にスペースを追加します)。

追加の引数を渡した場合、その%sフィールドに使用されます。たとえば、printf %100s abcは、97のスペース(「abc」の3を考慮して合計100になる)を出力し、その後に実際の文字列「abc」。ただし、引数が指定されていない場合、形式指定は空またはnull引数(%sの場合は空の文字列、%dの場合は0になります)で埋められます。これは同じです。 printf %100s ''などの空の文字列が渡されたかのように。その結果、100文字のパディングのみが印刷されます。

したがって、すべてをまとめると、printf %100sの結果、100スペースが印刷されます。


現在、trは文字を入力から出力に変換するツールです。 2つの引数SET1とSET2をそれぞれ文字のセットとして受け取り、SET1の最初の文字をSET2の最初の文字に変換し、SET1の2番目の文字をSET2の2番目の文字に変換します。 trはstdinから入力を読み取り、それをstdoutに書き戻します(そのため、上記のようなパイプラインで非常に役立ちます)。trは、指定された文字列内のその文字のすべての出現を常に変換します。

たとえば、tr aeiou 12345は、小文字の母音をこの順序で1から5に変換するため、「queueing」は「q52523ng」に変換されます。 tr a-z A-Zなどの文字範囲を渡して、小文字を対応する大文字に変換することもできます。

したがって、tr " " "="は、文字列全体でスペースを等号に変換するだけです。最初のスペースは、引数として認識されるように引用符で囲む必要があります。 =は実際には引用されないneedではありませんが、そうすることで害はありません。 tr " " =も同じように機能します。


すべてをまとめて100スペースを印刷し、それぞれを等号に変換します。

うまくいけば、これで十分に説明できますが、それでも理解できないことがあれば、コメントを残してください。

13
filbranden

printfコマンドで使用 最初の引数 形式として 後続の引数を出力します。 printf %100sは、(左側の)スペースを使用して、100文字幅までパディングされた引数を出力します。 formatには引数が指定されていないため、空の文字列を1回フォーマットし、100個のスペースを出力します。あなたはそれを見ることができます:

$ printf %100s | hexdump -C
00000000  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |                |
*
00000064

(20はスペースの16進数です。*は前の行が繰り返されていることを意味します)

書式文字列は、おおよそC Xprintf指定子:%、書式設定された値を収めるためのオプションの幅、および使用する書式のタイプを使用します。 sは文字列フォーマットで、デフォルトでは文字列の左側にスペースが埋め込まれます。複数の形式、または他のリテラル部分がある可能性があります:printf "a%10sb\n" hello印刷

 a         xb.

trは、標準入力で選択された文字を選択された置換文字で置換します 、結果を標準出力に出力します。 tr " " "="には、置換する単一の文字(スペース)と、置換する単一の文字(等号)があります。したがって、入力のすべてのスペースを=に変換し、残りは変更しません。あなたもそれを試すことができます:

$ tr " " "="
hello world
hello=world

(「hello world」と入力しました)

複数の置換を行うことができます:tr abc defは、aをdに、bをeに、cをfに変換し、残りは変更しません。ここではprintfが安価に生成できるものだったため、これは単一の文字です。

パイプ|が原因 左側のコマンドの出力printf %100sは、右側のコマンドtr " " "="への入力として使用されます。つまり、100個の連続したスペースがtrに与えられ、それぞれが=に置き換えられ、新しい文字列が出力されます。

printf %100s | tr " " "="
====================================================================================================
11
Michael Homer