ヒアドキュメントの定義はここにあります:http: //en.wikipedia.org/wiki/Here_document
ヒアドキュメントにタブを入力するにはどうすればよいですか?このような:
cat > prices.txt << EOF
coffee\t$1.50
tea\t$1.50
burger\t$5.00
EOF
アップデート:
この質問で扱われる問題:
- タブ文字を展開する
- ドル記号を拡大しない間
- スクリプトなどのファイルにヒアドキュメントを埋め込む
ヒアドキュメントの定義はここにあります:http: //en.wikipedia.org/wiki/Here_document
ヒアドキュメントにタブを入力するにはどうすればよいですか?このような:
cat > prices.txt << EOF
coffee\t$1.50
tea\t$1.50
burger\t$5.00
EOF
アップデート:
この質問で扱われる問題:
TAB="$(printf '\t')"
cat > prices.txt << EOF
coffee${TAB}\$1.50
tea${TAB}\$1.50
burger${TAB}\$5.00
EOF
ヒアドキュメントをスクリプトに埋め込んで、別のファイルをまったく使用せずに変数に割り当てることができます。
#!/bin/bash
read -r -d '' var<<"EOF"
coffee\t$1.50
tea\t$1.50
burger\t$5.00
EOF
次にprintf
、または文字をタブecho -e
に展開します。\t
ファイルに出力できます:
printf "%s\n" "$var" > prices.txt
または、次を使用して変数の値をそれ自体に割り当てますprintf -v
。
printf -v var "%s\n" "$var"
現在var
、またはファイルには、prices.txt
の代わりに実際のタブが含まれています\t
。
ヒアドキュメントを変数に保存したり、ファイルに書き込んだりする代わりに、読み込んだまま処理できます。
while read -r item price
do
printf "The price of %s is %s.\n" $item $price # as a sentence
printf "%s\t%s\n" $item $price # as a tab-delimited line
done <<- "EOF"
coffee $1.50 # I'm using spaces between fields in this case
tea $1.50
burger $5.00
EOF
<<-
この場合、here doc 演算子を使用したことに注意してください。これにより、読みやすくするためにヒア ドキュメントの行をインデントできます。インデントはタブのみで構成する必要があります (スペースは使用できません)。
私の場合、ctrl-Vと入力してからctrl-Iと入力して、bashシェルにタブを挿入します。これは、タブをインターセプトするシェルを回避します。それ以外の場合は、「特別な」意味があります。Ctrl-Vの後にタブが続く場合も機能するはずです。
ヒアドキュメントにドル記号を埋め込む場合は、シェル変数の補間を無効にするか、エスケープするために各変数の前にバックスラッシュを付ける必要があります(つまり\$
)。
あなたのサンプルテキストを使用して、私はprices.txtにこのコンテンツを作成しました:
coffee\t.50
tea\t.50
burger\t.00
$1
とが設定されていないため$5
です。補間は、ターミネータを引用することでオフに切り替えることができます。次に例を示します。
cat > prices.txt <<"EOF"
他の人が言ったように、CTRL-V を入力してからタブを入力すると、入力時に単一のタブを挿入できます。
たとえば、テキストを貼り付けたい場合や、多くのタブを含む長いヒアドキュメントを入力したい場合などに、bash のタブ補完を一時的に無効にすることもできます。
bind '\C-i:self-insert' # disable tab-completion
# paste some text or type your here-doc
# note you don't use "\t" you just press tab
bind '\C-i:complete' # reenable tab-completion
編集: Mac 上でiTerm 2を使用している場合、タブ付きのコードを bash コマンド ラインに貼り付けることができる "リテラル タブ付きで貼り付け" オプションが追加されました。
正しい答えはすでに与えられていることに注意してください。しかし、私はより簡潔な答えに要約しようとしています。
1.ヒア ドキュメントにリテラル タブ文字を使用することを妨げるものは何もありません。
Bash プロンプトでリテラル タブを入力するには、エスケープする必要があります。エスケープ文字は ctrl-V です (これをオーバーライドするカスタム バインドがない場合)。
$ echo -n 't<ctrl-v><tab>ab' | hexdump -C
00000000 74 09 61 62 |t.ab|
00000004
ほとんどのプログラマーのエディターでは、リテラル タブ文字を挿入するのは簡単なはずです (一部のエディターではエスケープも必要な場合があります。Emacs では、ctrl-Q TAB でリテラル タブが挿入されます)。
読みやすくするために、リテラルのタブ文字ではなく、ある種のエスケープを使用する方がよい場合があります。Bash では、これには $'...' 文字列構文が便利です。
2.変数の展開を防ぐには、すべてのドル記号を引用するか、here doc ターミネータを引用符で囲みます。
$ hexdump -C <<HERE
> t<ctrl-v><tab>\$ab
HERE
00000000 74 09 24 61 62 0a |t.$ab.|
00000006
$ hexdump -C <<'HERE'
> t<ctrl-v><tab>$ab
HERE
00000000 74 09 24 61 62 0a |t.$ab.|
00000006
このコンテキストでは、一重引用符または二重引用符のどちらを使用するかは問題ではありません。
3.このサブクエスチョンを理解しているかどうか確信が持てません。ヒア ドキュメントの目的は、それをスクリプトに埋め込むことです。前の例は、スクリプトまたはコマンド ラインでヒア ドキュメントを hexdump に渡す方法を示しています。
同じヒア ドキュメントを複数回使用したい場合、それを直接行う簡単な方法はありません。スクリプトは、ヒア ドキュメントを一時ファイルに書き込み、その一時ファイルを複数のコマンドに渡し、一時ファイルを消去することができます。trap
(スクリプトが中断された場合に備えて、一時ファイルの削除にも注意してください。)
ヒア ドキュメントの内容を変数に入れ、それを補間することもできます。
# Note embedded newlines inside the single quotes,
# and the use of $'...\t...' to encode tabs
data=$'coffee\t$1.50
tea\t$1.50
burger\t$5.00'
# Run Word Count on the data using a here document
wc <<HERE
$data
HERE
# Count number of tab characters using another here document with the same data
grep -c $'\t' <<HERE
$data
HERE
同様に使用できますecho -E "$data" | wc; echo -E "$data" | grep -c $'\t'
が、エコーの使用はあまりエレガントではなく、移植性が低くなる可能性があります (ただし、ターゲットが bash の場合、すべてのエコーは同じである必要があります。ターゲットが一般的に Bourne シェルの場合、エコーごとに外部プロセスを使用することもできます)。 )。
Re: サブ質問 #3、私はこの質問を次のように読みました。
「後で参照できるように、コメント付きのヒアドキュメントをスクリプトと同じファイルに保存したい場合はどうすればよいでしょうか?」
エグゼキュータにも書き込み権限があると仮定して、置換ではなく追加して、ヒア ドキュメントの出力としてスクリプト名を使用します。シェル コメントは、here doc ブロックでは解釈されません。
_thisline=${LINENO}
cat <<EOF >>$0
#====== $(date) =========
#On this run, these variable values were used as of line ${_thisline}: A=${A}, B=${B}, B=${C}
EOF
同様の方法で、ヒア ドキュメントを使用して、変数を値に展開する新しいスクリプトを書き出すことができます。それを実行すると、コードをトレースするのではなく、実行された内容の正確な記録が得られます。
sed のようなツールを使用して区切り文字 (EOF) を引用すると、作業がより簡単になります。
sed 's/\\t/\t/g' > prices.txt << 'EOF'
coffee\t$1.50
tea\t$1.50
burger\t$5.00
EOF
\\t
、次のようなより複雑な sed 呼び出しが必要になりますsed -e 's/\\t/\t/g' -e 's/\\\t/\\t/g'
。