値が6の変数があります。
$ echo $line_number
6
sedを使用して0から6以外のすべての行を削除すると、期待どおりに機能します。
$ sed "0,6!d" ~/myfile
数値6を変数に置き換えようとするとエラーが発生します。
$ sed "0,$line_number!d" ~/myfile
bash: !d": event not found
答え1
ここでの問題は、!
インタラクティブbash
の場合、二重引用符内でもトリガーされる文字です。歴史的拡張。
この機能はcsh(実際は悪い)で提供されており、bashとzshでも見つけることができますが、それ以外の標準機能ではsh
ありません。
bash
とは対照的に、履歴拡張zsh
はcsh
一重引用符内で発生しないため、sed '0,6!d'
問題はありません。しかしsed "0,6!d"
まだではない。インタラクティブbash
シェルを!d
含めるように拡張しますd
。
!
次のようにして特別な意味を取り除くことができます。
sed "0,$line_number"'!d'
最新のシェルにはより良いインタラクティブ機能があるため、個人的に履歴拡張機能を無効にします。私はzsh
withで無効にし、あなたはset +o banghist
withで無効にすることができます(実際には1997年に3.1.2との互換性のためにエイリアスとして追加されたので、withでも使用できます)。では、を使用して履歴拡張を無効にできます。実際には同じ方法が適用されます。bash
set +o histexpand
zsh
histexpand
banghist
bash
set +o histexpand
zsh
(t)csh
set histchars
histchars=
bash
zsh
この0
アドレスはGNUsed
拡張です。移植可能な場合は、次のものを使用できますhead
(より効率的です)。
head -n "$line_number"
ポータブルの場合は、sed
次のものを使用できます。
sed "${line_number}q"
また、読み続けて他のすべての行を削除するよりも、1行目以降の読み取りを停止するため、より効率的です。sed
$line_number