2

スクリプトを使用して、コマンドを使用してファイルの最後の n-2 行を取得し、echo を使用してこの行をファイルに出力しています。

last_n2_lines=`tail -n+3 $file`
echo "$last_n2_lines" >> $file

ここでのこのエコーは、ファイルの末尾から末尾の改行を削除します。ご参考までに

tail -n+3 ファイル > file.new

完全にうまく機能しています。

4

2 に答える 2

3

マニュアルから: http://www.gnu.org/software/bash/manual/bashref.html#Command-Substitution

3.5.4 コマンド置換

コマンド置換を使用すると、コマンドの出力をコマンド自体に置き換えることができます。コマンド置換は、コマンドが次のように囲まれている場合に発生します。

$(command)

また

`command`

Bash は、コマンドを実行し、コマンド置換をコマンドの標準出力に置き換え、末尾の改行を削除して展開を実行します。埋め込まれた改行は削除されませんが、単語分割中に削除される場合があります。コマンド置換 $(cat file) は、同等で高速な $(< file) に置き換えることができます。

古いスタイルの逆引用符形式の置換が使用される場合、バックスラッシュは、'$'、'`'、または '\' が続く場合を除いて、その文字どおりの意味を保持します。バックスラッシュが前にない最初の逆引用符は、コマンド置換を終了します。$(command) 形式を使用する場合、括弧内のすべての文字がコマンドを構成します。特別に扱われることはありません。

コマンド置換は入れ子にすることができます。逆引用符で囲まれた形式を使用するときにネストするには、内側の逆引用符をバックスラッシュでエスケープします。

置換が二重引用符で囲まれている場合、単語の分割とファイル名の展開は結果に対して実行されません。

鉱山を強調します。したがって、これはバグではありません。特徴です。

于 2013-02-10T09:39:03.580 に答える
2

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 番目のステートメントは、読み込まれたすべてのものを変更せずに出力します。

于 2013-02-10T10:05:10.360 に答える