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


8

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

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

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

printf %100s | tr " " "="

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

回答:


13

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

それを分解する:


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

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

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

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


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

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

だから、tr " " "="単純に文字列全体に等号にスペースを翻訳しています。最初のスペースは、引数として認識されるように引用符で囲む必要があります。=実際にはありません必要クオートするが、これは悪くはありません。tr " " =同じように機能します。


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

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


チェックするだけで、次の方が構文的に正しいでしょうか?:printf '%100s' ' ' | tr " " "="
LinuxSecurityFreak

2
@Vlastimil実際printf '%100s' ''には、空の文字列で...それを含めるように答えを更新しました。この特定のケースでは、空の文字列または単一のスペースは違いを生じませんが、とは異なりますがprintf '%sx\n'、にはprintf '%sx\n' ''違いがありprintf '%sx\n' ' 'ます。お役に立てば幸いです。
filbranden

1
+1 trは、文字のセットで機能することを示します。これはしばしば省略されます。
Sergiy Kolodyazhnyy

11

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」と入力しました)

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

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

printf %100s | tr " " "="
====================================================================================================

チェックするだけで、次の方が構文的に正しいでしょうか?:printf '%100s' ' ' | tr " " "="
LinuxSecurityFreak

1
スペースをフォーマットしてスペースでパディングすると、空の文字列をフォーマットしてスペースでパディングするのと同じ出力が得られますが、構造的に同等ではありません。おそらく、何が起こっているのかについての明確さの点ではより「正しい」が、構文的にはそうではなく、それらは異なるコマンドです。
Michael Homer
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.