一重引用符やその他の特殊文字を含む文字列を印刷する

一重引用符やその他の特殊文字を含む文字列を印刷する

これを AIX スクリプトで正しく記述するにはどうすればよいでしょうか? 要件は、このコマンドを test.txt に記述することです。

clock=$(prtconf -s | awk '{print $4,$5}')

このコマンドを試しました:

print 'clock=$(prtconf -s | awk '{print $4,$5}')' > test.txt

test.txt に書き込まれた出力は次のようになります。

clock=$(prtconf -s | awk {print ,})

引用符を使用する場合" ":

print "clock=$(prtconf -s | awk '{print $4,$5}')"

それは私に直接次のことを与えます:

clock=3612 MHz

これをどうすれば解決できますか?

答え1

最も簡単な方法は、'…'文字列を一重引用符で囲むことです。一重引用符はリテラル文字列を区切るため、一重引用符以外の文字をその間に挿入できます。文字列に一重引用符を挿入するには、4 文字のシーケンス(一重引用符、バックスラッシュ、一重引用符、一重引用符)'を使用します。'\''

技術的には、一重引用符で囲まれたリテラルの中に一重引用符を入れることはできません。しかし、連続したリテラルは一重引用符で囲まれたリテラルと同じ効果があります。'foo'\''bar'は次のように解析されます。

  1. 一重引用符で囲まれたリテラルfoo
  2. バックスラッシュで引用されたリテラル文字'
  3. 一重引用符で囲まれたリテラルbar

これは実質的に、'\''単一引用符で囲まれたリテラル内の単一引用符をエスケープする方法であることを意味します。

kshprintコマンドはバックスラッシュ展開を実行することに注意してください。-rこれを回避するには、オプションを追加します。印刷する文字列にバックスラッシュがない場合は問題はありませんが、-rメンテナンス中にバックスラッシュが追加された場合に備えて、 を使用することをお勧めします。

print -r -- 'clock=$(prtconf -s | awk '\''{print $4,$5}'\'')' > test.txt

あるいは、POSIX メソッドを使用して、最後に改行を付けて文字列を文字通り印刷することもできます。

printf '%s\n' 'clock=$(prtconf -s | awk '\''{print $4,$5}'\'')' > test.txt

答え2

一重引用符を使い続けて、出力で必要なものを「別々に」印刷するか、二重引用符を使用してドル記号をエスケープする必要があります。

2番目のオプションの場合:

print "clock=\$(prtconf -s | awk '{print \$4,\$5}')" > test.txt

まず第一に:

print 'clock=$(prtconf -s | awk '\''{print $4,$5}'\'')' > test.txt

(その後'text'、一重引用符がエスケープされます。)\''other text'

完全を期すために、 はprintバックスラッシュ文字のエスケープ シーケンスを展開することに注意してください (印刷する文字列にバックスラッシュが含まれていないため、これは問題になりません)。これを回避するには、 を使用しますprint -r

答え3

@Mat が言ったように、2 つの解決策があります。

1] シングルクォートの使用': このシングルクォートは、エスケープ文字、$さまざまなコマンド(基本的にすべてのbash構造とunixコマンド)の特別な意味を削除します。printコマンドはすべてをプレーン文字として受け取り、ファイルに書き込みます。test.txt

2] 二重引用符の使用": ここでは、bash 構造を明示的にエスケープする必要があります。\$の特別な意味$、つまり の後に使用される変数の値を削除します$

答え4

なぜここに文書?

cat <<'END' > test.txt
clock=$(prtconf -s | awk '{print $4,$5}')
END

ENDの周りの引用符に注意してください<<'END'。引用符は、次の行(マーカーまで)のテキストがEND文字通り使用されることを意味します。 のみを使用すると<<END、ドル展開(つまり、$(command)または$variable)が実行されます。

関連情報