スクリプトを使用して、コマンドを使用してファイルの最後の n-2 行を取得し、echo を使用してこの行をファイルに出力しています。
last_n2_lines=`tail -n+3 $file`
echo "$last_n2_lines" >> $file
ここでのこのエコーは、ファイルの末尾から末尾の改行を削除します。ご参考までに
tail -n+3 ファイル > file.new
完全にうまく機能しています。
マニュアルから: http://www.gnu.org/software/bash/manual/bashref.html#Command-Substitution
3.5.4 コマンド置換
コマンド置換を使用すると、コマンドの出力をコマンド自体に置き換えることができます。コマンド置換は、コマンドが次のように囲まれている場合に発生します。
$(command)
また
`command`
Bash は、コマンドを実行し、コマンド置換をコマンドの標準出力に置き換え、末尾の改行を削除して展開を実行します。埋め込まれた改行は削除されませんが、単語分割中に削除される場合があります。コマンド置換 $(cat file) は、同等で高速な $(< file) に置き換えることができます。
古いスタイルの逆引用符形式の置換が使用される場合、バックスラッシュは、'$'、'`'、または '\' が続く場合を除いて、その文字どおりの意味を保持します。バックスラッシュが前にない最初の逆引用符は、コマンド置換を終了します。$(command) 形式を使用する場合、括弧内のすべての文字がコマンドを構成します。特別に扱われることはありません。
コマンド置換は入れ子にすることができます。逆引用符で囲まれた形式を使用するときにネストするには、内側の逆引用符をバックスラッシュでエスケープします。
置換が二重引用符で囲まれている場合、単語の分割とファイル名の展開は結果に対して実行されません。
鉱山を強調します。したがって、これはバグではありません。特徴です。
readarray
を使用してデータを保存し、出力することで、末尾の空行を保持できprintf
ます。
何かのようなもの:
readarray last_n2_lines < <(tail -n+3 $file)
printf "%s" "${last_n2_lines[@]}" > ${file}.new
デモ:
$ cat test; echo end
1
2
3
4
end
$ tail -n+3 test ; echo end
3
4
end
$ readarray data < <(tail -n+3 test)
$ printf "%s" "${data[@]}" ; echo end
3
4
end
説明:
readarray data
は、標準入力から という配列に行を読み取りますdata
。cmd1 < <(cmd2 param1 param2 ...)
cmd2 param1 param2 ...
の出力を標準入力 if にリダイレクトしますcmd1
。構文に注意してください: it must be < [space] <(...)
, 間にスペースを入れないでください , 間<(
にスペースが必要です< <
.したがって、最初の行の後に、出力data
するすべての行が含まれtail -n+3
ます。配列内の各項目は、行末記号を含む入力の行です。
各要素にアクセスする方法は次のとおりです。配列で定義された項目ごとに 2 行が出力されることに注意してください。配列内の行 (改行を含む) と、 によって追加された改行echo
です。
$ echo "${data[0]}"
3
$ echo "${data[1]}"
4
$ echo "${data[2]}"
$ echo "${data[3]}"
$ echo "${data[4]}" # out of bounds
$
${data[@]}
配列のすべての要素に展開しますdata
printf "%s" param1 param2 ...
すべての引数を変更せずに表示します (つまり、行末記号を追加または削除しません)。したがって、2 番目のステートメントは、読み込まれたすべてのものを変更せずに出力します。