Bashでのゴルフのヒント


55

Bashでゴルフをするための一般的なヒントは何ですか?私は、少なくともBashに特有のゴルフ問題全般のコーディングに適用できるアイデアを探しています(たとえば、「コメントの削除」は答えではありません)。回答ごとに1つのヒントを投稿してください。

回答:


36

文書化されていませんが、レガシーsh後方互換性のために私が遭遇したすべてのバージョンで動作します:

forループを使用すると、の{ }代わりに使用できますdo done。例:置換:

for i in {1..10};do echo $i; done

で:

for i in {1..10};{ echo $i;}

どんなシェルがshこのfor構文を許可するのですか?で明示的に許可されていzshます。
mikeserv

@mikeservバッシュ。私はどこかでこの構文が古いもので許可されてshいたことと、そのためにBashでも許可されていることをどこかで読んだことを覚えていますが、残念ながら引用はありません。
デジタル外傷

ああ... csh、おそらく-それは彼らがそのシェルで働いた方法です。
mikeserv

ところで、中にksh93上記のことが考えられます;{1..10}し、中bashprintf %s\\n {1..10}
mikeserv

1
for((;i++<10)){ echo $i;}より短いfor i in {1..10};{ echo $i;}
エヴァンクラル

29

算術膨張使用するための$[…]代わりの$((…))

bash-4.1$ echo $((1+2*3))
7

bash-4.1$ echo $[1+2*3]
7

算術展開では使用しないでください$

bash-4.1$ a=1 b=2 c=3

bash-4.1$ echo $[$a+$b*$c]
7

bash-4.1$ echo $[a+b*c]
7

インデックス付き配列の添字に対して算術展開が実行されるため、$どちらも使用しないでください。

bash-4.1$ a=(1 2 3) b=2 c=3

bash-4.1$ echo ${a[$c-$b]}
2

bash-4.1$ echo ${a[c-b]}
2

算術展開では使用しないでください${…}

bash-4.1$ a=(1 2 3)

bash-4.1$ echo $[${a[0]}+${a[1]}*${a[2]}]
7

bash-4.1$ echo $[a[0]+a[1]*a[2]]
7

交換while((i--))して、働く、while[i--]またはwhile $[i--]私のために動作しませんでした。GNU bash、バージョン4.3.46(1)
グレンランダース-パーソン

1
正しい、@ GlennRanders-Pehrson。それは機能するはずがありません。
マナトワーク

y=`bc<<<"($x*2.2)%10/1"`... bc整数以外の計算に使用する例... /1最後に、結果の小数が整数に切り捨てられることに注意してください。
ロブログ

s=$((i%2>0?s+x:s+y))... bash算術で三項演算子を使用する例。それはより短いですif..then..else[ ] && ||
roblogic

1
@manatworkありがとう。彼らはそれを削除したに違いありません。私は上にGNU bash, version 5.0.2(1)-release (x86_64-apple-darwin16.7.0)あり、それは私のものではありません。
ヨナ

19

関数を定義する通常の、長くて退屈な方法は

f(){ CODE;}

この男が見つけた、あなたは絶対に前にスペース必要CODEとそれの後にセミコロンを。

これは、@ DigitalTraumaから学んだ小さなトリックです

f()(CODE)

これは2文字短く、同様に機能します。ただし関数が戻った後、変数の値の変更を引き継ぐ必要はありません(括弧は本体をサブシェルで実行します)。

@ jimmy23013はコメントで指摘し、でも、括弧は不要です。

Bashのリファレンスマニュアルは、次のような機能を定義することができることを示しています。

name () compound-command [ redirections ]

または

function name [()] compound-command [ redirections ]

複合コマンドを使用できます

  • ループ構造:untilwhileまたはfor
  • 条件付き構築物:ifcase((...))または[[...]]
  • グループ化されたコマンド:(...)または{...}

つまり、次のすべてが有効です。

$ f()if $1;then $2;fi
$ f()($1&&$2)
$ f()(($1))                # This one lets you assign integer values

そして、私は吸盤のような中括弧を使用しています...


2
f()while ... f()if ...およびその他の複合コマンドも使用できることに注意してください。
jimmy23013 14年

これf()CODEは合法だと思ったので驚いた。これはf()echo hi、pdkshとzshでは有効ですが、bashでは有効ではありません。
カーニグ14年

1
forデフォルトでポジショニング:f()for x do : $x; done;set -x *;PS4=$* f "$@"または何かになっているため、特に便利です。
mikeserv

16

:は何もしないコマンドで、終了ステータスは常に成功するため、の代わりに使用できますtrue


サブシェルとパイピングを使用すると、ほぼ同じバイト数が使用されますが、パイピングはより実用的です。
ckjbgames

5
あなたが行う場合を除き:(){:|:}
enedil

14

その他のヒント

  1. 三項演算子、((test)) && cmd1 || cmd2または[ test ] && cmd1 || cmd2をできるだけ乱用します。

    例(長さのカウントは常に最上行を除外します):

    t="$something"
    if [ $t == "hi" ];then
    cmd1
    cmd2
    elif [ $t == "bye" ];then
    cmd3
    cmd4
    else
    cmd5
    if [ $t == "sup" ];then
    cmd6
    fi
    fi
    

    三項演算子のみを使用すると、これを簡単に次のように短縮できます。

    t="$something"
    [ $t == "hi" ]&&{
    cmd1;cmd2
    }||[ $t == "bye" ]&&{
    cmd3;cmd4
    }||{
    cmd5
    [ $t == "sup" ]&&cmd6
    }
    

    nyuszika7hがコメントで指摘したように、この特定の例は次を使用してさらに短縮できますcase

    t="$something"
    case $t in "hi")cmd1;cmd2;;"bye")cmd3;cmd4;;*)cmd5;[ $t == "sup" ]&&cmd6;esac
    
  2. また、可能な限り括弧を括弧で囲みます。括弧は単語ではなくメタ文字であるため、どのようなコンテキストでもスペースを必要としません。これは、サブシェルで可能な限り多くのコマンドを実行することも意味します。中括弧({および})はメタ文字ではなく予約語であり、したがって、正しく解析するには両側に空白が必要ですが、メタ文字はそうではありません。サブシェルは親環境に影響を与えないことをご存知だと思いますので、すべてのサンプルコマンドをサブシェルで安全に実行できると仮定すると(いずれの場合も一般的ではありません)、上記のコードをこれに短縮できます:

    t=$something
    [ $t == "hi" ]&&(cmd1;cmd2)||[ $t == "bye" ]&&(cmd3;cmd4)||(cmd5;[ $t == "sup" ]&&cmd6)
    

    また、できない場合は、かっこを使用することで多少縮小することもできます。覚えておくべきことの1つは、整数に対してのみ機能するため、この例の目的には役に立たないことです(ただし-eq、整数に使用するよりもはるかに優れています)。

  3. もう1つ、可能な場合は引用符を避けます。上記のアドバイスを使用して、さらに縮小できます。例:

    t=$something
    [ $t == hi ]&&(cmd1;cmd2)||[ $t == bye ]&&(cmd3;cmd4)||(cmd5;[ $t == sup ]&&cmd6)
  4. テスト条件では、いくつかの例外を除いて、できる限りシングルブラケットをダブルブラケットにすることをお勧めします。2文字を無料でドロップしますが、場合によってはそれほど堅牢ではありません(Bash拡張機能-例については以下を参照)。また、doubleではなく、単一のequals引数を使用します。ドロップする無料のキャラクターです。

    [[ $f == b ]]&&: # ... <-- Bad
    [ $f == b ]&&: # ... <-- Better
    [ $f = b ]&&: # ... <-- Best.  word splits and pathname-expands the contents of $f.  Esp. bad if it starts with -

    特に、null出力または未定義の変数をチェックする際には、この警告に注意してください。

    [[ $f ]]&&:    # double quotes aren't needed inside [[, which can save chars
    [ "$f" = '' ]&&: <-- This is significantly longer
    [ -n "$f" ]&&:

    技術的には、この特定の例はcase... が最適ですin

    t=$something
    case $t in hi)cmd1;cmd2;;bye)cmd3;cmd4;;*)cmd5;[ $t == sup ]&&cmd6;esac

したがって、この投稿の教訓は次のとおりです。

  1. ブール演算子をできるだけ乱用し、/ / etcの代わりに常に使用します。構成します。ifif-else
  2. 括弧はメタ文字であり、予約語ではないため、可能な限り括弧を使用し、サブシェルでできるだけ多くのセグメントを実行します。
  3. 物理的に可能な限り引用符を避けます。
  4. 特に文字列マッチングでは、かなりのバイト数を節約できるため、case...をチェックしてくださいin

PS:コンテキストに関係なく、Bashで認識されるメタ文字のリストを以下に示します(単語を分離できます)。

&lt; &gt; ( ) ; & | &lt;space&gt; &lt;tab&gt;

編集:manatworkが指摘したように、二重括弧テストは整数に対してのみ機能します。また、間接的に、==演算子を囲む空白が必要であることがわかりました。上記の私の投稿を修正しました。

また、各セグメントの長さを再計算するのが面倒だったので、単純にそれらを削除しました。必要に応じて、オンラインで文字列の長さ計算機を見つけるのは簡単です。


申し訳ありませんが、重大なエラーがいくつかあります。[ $t=="hi" ]として解析されるため、常に0に評価され[ -n "STRING" ]ます。(($t=="hi"))文字列は算術評価で整数に強制されるため、$ tが非数値である限り、常に0に評価されます。いくつかのテストケース:pastebin.com/WefDzWbL
manatwork

@manatworkキャッチしてくれてありがとう。それに応じて更新します。
イサイアメドウズ14

ここでは、aの使用caseが短くなります。また、前}にスペースは必要ありませんが、後に必要です{
nyuszika7h 14年

1
なぜ=より堅牢では==ないのでしょうか?=POSIXによって義務付けられて==いますが、そうではありません。
デニス14

1
質問はを頼むん答えにつき1つの先端 ...
トビースパイツ

7

代わりにgrep -Egrep -Fgrep -r、使用egrepfgreprgrep、2つの文字を保存します。短いものは非推奨ですが、正常に機能します。

(回答ごとに1つのヒントをお願いしました!)


1
残念Pgrepですgrep -Ppgrepプロセスを検索するために使用されると簡単に混同される可能性がありますが、
nyuszika7h 14

1
@私は個人的に使用nyuszika7h grep -oたくさん

スペースを含めて3つ節約できませんか?
ckjbgames

7

配列の要素0は、変数名のみでアクセスできます。インデックス0を明示的に指定すると、5バイト節約されます。

$ a=(code golf)
$ echo ${a[0]}
code
$ echo $a
code
$ 

7

変数の内容をパイプラインの次のプロセスのSTDINに渡す必要がある場合、一般的に変数をパイプラインにエコーします。しかし、<<< bash here文字列で同じことを実現できます

$ s="code golf"
$ echo "$s"|cut -b4-6
e g
$ cut -b4-6<<<"$s"
e g
$ 

2
私たちがゴルフをしているので、s=code\ golfecho $s|および<<<$s(を念頭に置いているなど、何の繰り返しにスペースがないという理由だけで、後者の2つの作品)。
デニス14年

6

避けてください$( ...command... )、1つの文字を保存して同じことをする代替案があります:

` ...command... `

9
$( )ネストされたコマンド置換がある場合に必要になることがあります。それ以外の場合は、内側から脱出する必要があります``
デジタル外傷

1
これらは技術的に異なることを行います。たとえば$()scpターゲットマシンの代わりに自分のマシンで置換を実行したいときではなく、バックティックを使用する必要がありました。ほとんどの場合、それらは同一です。
地下

2
@undergroundmonorail:バックティックは必要ありません。$()適切に引用すれば、彼らができることは何でもできます。($バックティックスではなく、むさぼる何かを生き残るためにあなたの命令が必要でない限り)。それらの中にあるものを引用する際に、微妙な違いがいくつかあります。 mywiki.wooledge.org/BashFAQ/082にはいくつかの違いが説明されています。ゴルフをしているのでなければ、バックティックを使用しないでください。
ピーターコーデス

@PeterCordes 方法あると思いますが、当時試したすべてがうまくいきませんでした。バックティックが最良の解決策ではなかったとしても、それが私が持っていた唯一の解決策だったので、私はそれらについて知っていて良かったです。¯\ _(ツ)_ /¯–
地下

@DigitalTraumaネスティングのサンプル:echo `bc <<<"\`date +%s\`-12"`...(コメントにバック
ティック

6

ifコマンドをグループ化するために使用

を削除するこのヒントと比較すると、これは、ifからの戻り値が必要な場合など、非常にまれなケースでのみうまく機能するはずですif

次のifようにで終わるコマンドグループがある場合:

a&&{ b;if c;then d;else e;fi;}
a&&(b;if c;then d;else e;fi)

if代わりに、条件の前にコマンドをラップできます。

a&&if b;c;then d;else e;fi

または、関数が次で終わる場合if

f(){ a;if b;then c;else d;fi;}

中括弧を削除できます。

f()if a;b;then c;else d;fi

1
[test] && $if_true || $elseこれらの関数で三項演算子を使用して、いくつかのバイトを節約できます。
ckjbgames

また、あなたの周りのスペースを必要としない&&||
roblogic

6

(( ... ))条件に算術を使用する

交換できます:

if [ $i -gt 5 ] ; then
    echo Do something with i greater than 5
fi

沿って

if((i>5));then
    echo Do something with i greater than 5
fi

(注:後にスペースはありませんif

あるいは

((i>5))&&{
    echo Do something with i greater than 5
}

...または1つのコマンドのみの場合

((i>5))&&echo Echo or do something with i greater than 5

さらに:算術構文の変数設定を非表示にします。

((i>5?c=1:0))&&echo Nothing relevant there...
# ...
((c))&&echo Doing something else if i was greater than 5

または同じ

((c=i>5?c=0,1:0))&&echo Nothing relevant there...
# ...
((c))&&echo Doing something else if i was greater than 5

...ここで、i> 5の場合、c = 1(0ではない;)


[ ]代わりにを使用すると、2バイト節約できます(())
ckjbgames

@ckjbgames確かに!?Wich bashバージョンを使用していますか?
F. HAURI

@FHauriバイトの点ではほぼ同じだと思います。
ckjbgames

@ckjbgamesでは[ ]、変数にドル記号が必要です。を使用して同じまたはより短い長さで同じことができる方法がわかりません[ ]
F. HAURI

ボーナスヒント:forループの最初の行がで始まる場合、((...))改行やスペースは不要です。たとえばfor((;10>n++;)){((n%3))&&echo $n;} 、オンラインでお試しください!
プリモ

6

無限ループ(breakor exitステートメントでエスケープ可能)の短い構文は次のとおりです。

for((;;)){ code;}

これは、より短いwhile true;while :;

breakexitエスケープする唯一の方法として)必要ない場合は、代わりに再帰関数を使用できます。

f(){ code;f;};f

ブレークする必要があるが、終了する必要はなく、変数の変更をループ外に持ち越す必要がない場合、サブシェルで関数bodyを実行するbodyの周りに括弧を付けて再帰関数使用できます。

f()(code;f);f

6

1行のforループ

範囲拡張と連結された算術式は、範囲内の各アイテムに対して評価されます。たとえば、次のとおりです。

: $[expression]{0..9}

expression10回評価されます。

多くの場合、これは同等のforループよりも大幅に短くなります。

for((;10>n++;expression with n)){ :;}
: $[expression with ++n]{0..9}

コマンドが見つからないというエラーを気にしない場合は、initalを削除できます:。10を超える反復の場合、文字範囲を使用することもできます{A..z}。たとえば、58回反復します。

実際の例として、次の両方は、それぞれ独自の行にある最初の50個の三角形の数を生成します。

for((;50>d++;)){ echo $[n+=d];} # 31 bytes
printf %d\\n $[n+=++d]{A..r}    # 28 bytes

あなたはまた、逆方向に反復することができますfor((;0<i--;)){ f;}
roblogic

5

引数をループする

「in foo bar…」部分のないBashの「for」ループで述べたように、in "$@;"in for x in "$@;"は冗長です。

からhelp for

for: for NAME [in WORDS ... ] ; do COMMANDS; done
    Execute commands for each member in a list.

    The `for' loop executes a sequence of commands for each member in a
    list of items.  If `in WORDS ...;' is not present, then `in "$@"' is
    assumed.  For each element in WORDS, NAME is set to that element, and
    the COMMANDS are executed.

    Exit Status:
    Returns the status of the last command executed.

たとえば、Bashスクリプトまたは関数への位置引数を指定してすべての数値を2乗する場合、これを実行できます。

for n;{ echo $[n*n];}

オンラインでお試しください!


5

猫の代わり

ファイルを読み取って、他のファイルで使用しようとしているとします。あなたがするかもしれないことは:

echo foo `cat bar`

内容が場合barだったfoobar、これは印刷しfoo foobar

ただし、3バイトを節約するこの方法を使用している場合は、別の方法があります。

echo foo `<bar`

1
<bar単独では機能しませんが、バックティックに配置することで機能する理由はありますか?
KritixiのLithos

@Cowsquackはい。<コマンドにファイルを置きますが、この場合には、それが原因癖に標準出力にそれを置きます。バックティックはこれを一緒に評価します。
Okx

標準入力から読み取るより短い方法はあり`cat`ますか?
ジョエル

4

可能な場合との[代わりに使用する[[test

例:

[ -n $x ]


比較の=代わりに使用==

例:

[ $x = y ]

等号の前後にスペースが必要です。そうしないと機能しません。同じことが==私のテストに基づいて適用されます。


3
[対は、[[必要な引用符の量に依存してもよい:pastebin.com/UPAGWbDQ
manatwork

@manatworkそれは良い点です。
nyuszika7h

1
一般的なルール:[... ]== /bin/test、しかし[[... ]]!= /bin/testと1を好むことはありません[... ][[... ]]codegolfの外

4

に代わるもの head

lineは3バイトよりも短いですがhead -1廃止予定です

sed qは、より2バイト短いですhead -1

sed 9qは、よりも1バイト短くなっていhead -9ます。


1
けれども運命、我々はまだしばらくの間、使用することができますlineからのutil-linuxの一行を読み込むためにパッケージ。
マナトワーク

4

tr -cd より短い grep -o

たとえば、スペースをカウントする必要がある場合、grep -o <char>(一致したもののみを印刷する)10バイトを与え、tr -cd <char>(補数を削除する<char>)は9 バイトを与えます。

# 16 bytes
grep -o \ |wc -l
# 15 bytes
tr -cd \ |wc -c

ソース

どちらもわずかに異なる出力を提供することに注意してください。grep -o行で区切られた結果を返しますtr -cdが、それらはすべて同じ行に表示されるため、tr常に好ましいとは限りません。


4

ファイル名を短くする

最近の課題では、ファイルを読み取ろうとしましたが、その形式のファイルは他に存在しない/sys/class/power_supply/BAT1/capacityため/*/*/*/*/capac*y、これを短くすることができます。

たとえばfoo/、ファイルfoo, bar, foobar, barfooを含むディレクトリがあり、そのファイルを参照したいfoo/barfoo場合、を使用foo/barf*してバイトを保存できます。

*「何を」であり、正規表現と等価です.*


3

:コマンドの代わりにパイプを使用し/dev/nullます。:ビルトインは、そのすべての入力を食べるようになります。


2
いいえ、ほとんどの場合、SIGPIPEでプログラムをクラッシュさせます。echo a|tee /dev/stderr|:何も印刷しません。
jimmy23013 14年

レースがあります:echo a|tee /dev/stderr|:私のコンピューターでaを印刷しましたが、他の場所ではSIGPIPEが最初にティーを殺すかもしれません。のバージョンに依存する場合がありteeます。
カーニグ14年

はい、それはSIGPIPEの問題です。tee >(:) < <(seq 1 10)動作しますが、動作しtee /dev/stderr | :ません。でも、a() { :;};tee /dev/stderr < <(seq 1 10)| a何も印刷されません。
F.ハウリ

@ user16402-あなたは私の視野にFCC名を持っている必要があります...とにかく、:組み込み関数まったく食べません...コロンへの入力を仮定すると、エラーをパイプにあふれさせる可能性があります...しかし、リダイレクトをフロートすることができますコロンを使用するか、それを使用してプロセスをドロップします... :| while i>&$(($??!$?:${#?})) command shit; do [ -s testitsoutput ]; doneまたはその疑似提案が適用されます...また、あなたは私ほど幽霊っぽいことに気づいていますか?...すべてのコストを避ける< <(psycho shit i can alias to crazy math eat your world; okay? anyway, ksh93 has a separate but equal composite char placement)
mikeserv

3

split入力をN各行のセクションに分割するための別の(非推奨ですが、誰も気にしない)構文がありsplit -lNます:代わりにsplit -Neg を使用できますsplit -9


3

テストを拡大する

本質的に、シェルは一種のマクロ言語、または少なくともハイブリッドまたは何らかの種類です。すべてのコマンドラインは、基本的に、解析/入力部分と展開/出力部分の2つの部分に分けることができます。

最初の部分は、ほとんどの人が最もシンプルであるため、何に焦点を合わせているかです。あなたが得るものを見ることができます。2番目の部分は、多くの人が非常によく理解しようとしてさえ回避することであり、人々evalが悪のようなことを言い、常に拡張を引用する理由です。それは大丈夫です-しかし、それは不必要に長いコードブランチと大量の外部テストにつながります。

拡張は自己テストです。${param[[:]#%+-=?]word}フォームは、パラメータの内容を検証するために十分以上のものネスト可能であり、すべてのための評価に基づいていNUL -ほとんどの人はとにかくテストで期待するものです。+ループでは特に便利です。

r()while IFS= read -r r&&"${r:+set}" -- "$@" "${r:=$*}";do :;done 2>&-

IFS=x
printf %s\\n some lines\ of input here '' some more|{ r;echo "$r"; }

somexlines ofxinputxhere

... while read空行ではなくプルインが"${r:+set}"展開さ"set"れ、位置が$r追加されます。しかし、空白行がのread場合、$rは空で"${r:+set}"展開されます""-これは無効なコマンドです。ただし、nullコマンドが検索される前にコマンドラインが展開されるため、最初のバイトで連結されたすべての位置の値も取得します。複合コマンドで次の入力段落を取得するための別の値を使用して再度呼び出すことができます。これは、シェルが入力の次の改行を超えてバッファすることは違法であるためです。"""${r:=$*}"$IFSr()|{;}$IFSread\n


3

末尾再帰を使用して、ループを短くします。

これらは動作が同等です(ただし、メモリ/ PIDの使用法はおそらくそうではありません)。

while :;do body; done
f()(body;f);f
body;exec $0
body;$0

そして、これらはほぼ同等です。

while condition; do body; done
f()(body;condition&&f);f
body;condition&&exec $0
body;condition&&$0

(技術的には、最後の3つは常に少なくとも1回は本体を実行します)

を使用$0するには、bashプロンプトに貼り付けるのではなく、ファイルにスクリプトを含める必要があります。

最終的にはスタックがオーバーフローする可能性がありますが、いくつかのバイトを節約します。


3

expr通常の代わりに単純な算術式の結果を表示するために組み込みを使用する方が短い場合がありecho $[ ]ます。例えば:

expr $1 % 2

以下より1バイト短い

echo $[$1%2]

2

pwd代わりに使用してecho、出力の行を生成します

stdoutに行を追加する必要がありますが、内容は気にせず、シェルの組み込みコマンドへの回答を制限しますか?pwdは、より短いバイトですecho


2

文字列を印刷するときに引用符を省略することができます。

echo "example"
echo example

SM-T335 LTE、Android 5.1.1での出力:

u0_a177@milletlte:/ $ echo "example"
example
u0_a177@milletlte:/ $ echo example
example

2

非連続配列項目を割り当てる場合、連続チャンクの連続インデックスをスキップできます:

bash-4.4$ a=([1]=1 [2]=2 [3]=3 [21]=1 [22]=2 [23]=3 [31]=1)

bash-4.4$ b=([1]=1 2 3 [21]=1 2 3 [31]=1)

結果は同じです:

bash-4.4$ declare -p a b
declare -a a=([1]="1" [2]="2" [3]="3" [21]="1" [22]="2" [23]="3" [31]="1")
declare -a b=([1]="1" [2]="2" [3]="3" [21]="1" [22]="2" [23]="3" [31]="1")

によるとman bash

配列は、name =(value 1 ... value n)という形式の複合割り当てを使用して割り当てられます。各は[ subscript ] = stringの形式です。インデックス付き配列の割り当てには、string以外は必要ありません 。インデックス付き配列に割り当てるときに、オプションのブラケットと添え字が指定されている場合、そのインデックスが割り当てられます。それ以外の場合、割り当てられた要素のインデックスは、ステートメントに割り当てられた最後のインデックスに1を加えたものです。


追加に役立つ:初期化されていない要素は、算術展開では0に、他の展開では ""に展開されます。
デジタル外傷

2

文字列の最初の単語を出力します

文字列が変数内にaあり、エスケープ文字とフォーマット文字(\および%)を含まない場合は、これを使用します:

printf $a

ただし、結果を印刷する代わりに変数に保存する必要がある場合は、次のコードよりも長くなります。

x=($a)
$x

1

1つのfor命令で2つの埋め込みループを行う:

for ((l=i=0;l<=99;i=i>98?l++,0:++i)) ;do
    printf "I: %2d, L: %2d\n" $i $l
done |
    tee >(wc) | (head -n4;echo ...;tail -n 5)
I:  0, L:  0
I:  1, L:  0
I:  2, L:  0
I:  3, L:  0
...
I: 96, L: 99
I: 97, L: 99
I: 98, L: 99
I: 99, L: 99
  10000   40000  130000

1

引用符付き文字列の割り当てと印刷

引用符で囲まれた文字列を変数に割り当て、その変数の値を出力する場合、通常の方法は次のとおりです。

a="Programming Puzzles & Code Golf";echo $a

場合はa、以前の設定を解除し、これはに短縮することができます。

echo ${a=Programming Puzzles & Code Golf}

a以前に設定されていた場合、代わりにこれを使用する必要があります。

echo ${a+Programming Puzzles & Code Golf}

これは、文字列に引用符が必要な場合(たとえば、空白が含まれる場合)にのみ有用であることに注意してください。引用符a=123;echo $aがなければ、同じくらい短いです。


${a+foo}設定しませんa
GammaFunction
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.