ファイル内で行を回転させます。一番上の行を一番下に移動して日付を追加します。

ファイル内で行を回転させます。一番上の行を一番下に移動して日付を追加します。

スクリプトで変更したいリストがあります。スクリプトを実行するたびに回転リストを取得できるように、一番上の項目を一番下に移動したいと思います。また、一番下に移動した行に日付を追加したいと思います。したがって。最上位フォルダは、rclone を使用して以前のバックアップを保存するためにも使用されます。

old1
old2
old3

これに関して

old2
old3
old1 date time

使用しようとしたコードが見つかりましたが、上部アイテムが移動せずに下部にコピーするだけで、次のような出力が得られます。

old1
old2
old3
old1 date time
old1 date time

私が試したコード# Rotate the BACKUPLIST-file, deleting the top entry and adding a new entry at the bottom
OLDEST=$(head -1 $BACKUPLIST | sed 's/ .*//') # The oldest, extra backup-version COUNT=$(cat $BACKUPLIST | wc -l) # Number of files in list
((COUNT=$COUNT-1)) tail -$COUNT $BACKUPLIST > $BACKUPLIST.tmp echo $OLDEST $(date) >> $BACKUPLIST.tmp # Add a new line to the bottom, including today's date

答え1

フォーマット文字列から正しいエスケープを取得するのは少し面倒ですが、与えられたdate場合

$ cat file
old1
old2
old3

それから

$ cat << 'EOF' | ed -s file
1m$
r !date +\ \%x\ \%X
.-1,.j
,p
EOF
old2
old3
old1 2019-07-25 05:42:32 PM

または(一行で)

printf '%s\n' '1m$' 'r !date +\ \%x\ \%X' '.-1,.j' ',p' | ed -s file

ファイルを所定の位置に編集するには、p(印刷)をwq(書き込み終了)に置き換えます.もちろん、%xおよびを他の書式指定子に置き換えることもできます。%X

答え2

$ date +"$(head -n 1 file) %F %T" >>file; sed -i 1d file
$ cat file
old2
old3
old1 2019-07-25 23:39:51
$ date +"$(head -n 1 file) %F %T" >>file; sed -i 1d file
$ cat file
old3
old1 2019-07-25 23:47:10
old2 2019-07-25 23:47:22

これにより、file最初の行が出力形式に文字列として挿入されますdate。は%F略語で%Y-%m-%dあり、ほとんどの実装では略語です%T%H:%M:%Sdate

これにより出力がdate最後に追加されますfile

新しいデータを追加した後、sed前の最初の行を削除するために使用されます(内部編集を使用)。一部のsed実装は次のように呼び出す必要がありますsed -i '' 1d file(参照sed -i(所定の位置で編集)を使用して移植性を達成するには?)。


上記のコマンドを4番目に実行すると、次のような結果が表示されます。

$ date +"$(head -n 1 file) %F %T" >>file; sed -i 1d file
$ cat file
old2 2019-07-25 23:47:22
old3 2019-07-25 23:51:22
old1 2019-07-25 23:47:10 2019-07-25 23:51:24

これが必要ない場合は、次のようなものを使用してください

awk '{ print $1; exit }'

代わりに、head -n 1スペースで区切られた最初の項目を選択します。最初の行にはありますが、前の日付と時刻を含む最初の行全体ではありません。

答え3

Bashでこれをすばやく実行できます。

mapfile -t lines < file
printf "%s\n" "${lines[@]:1}" "${lines[0]} $(date "+%F %T")" > file

関数に入れてみてください:

rotate_file() {
    [[ -w "$1" ]] || return 1
    local -a lines
    mapfile -t lines < "$1"
    printf "%s\n" "${lines[@]:1}" "${lines[0]} $(date "+%F %T")" > "$1"
}

デモ:

$ cat file
1
2
3
$ rotate_file file
$ cat file
2
3
1 2019-07-25 17:16:51
$ rotate_file file
$ cat file
3
1 2019-07-25 17:16:51
2 2019-07-25 17:16:57

これにより、ファイル全体がメモリに保存されます。ファイルが大きいと、速度が遅くなる可能性があります。

答え4

$ hd="$(head -1 file)"; tail +2 file; printf '%s %s\n' "$hd" "$(date)"
old2
old3
old1 Thu, Jul 25, 2019  4:27:15 PM

$ hd="$(head -1 file)"; { tail +2 file; printf '%s %s\n' "$hd" "$(date)"; } > tmp && mv tmp file; cat file
old2
old3
old1 Thu, Jul 25, 2019  4:28:44 PM

$ hd="$(head -1 file)"; { tail +2 file; printf '%s %s\n' "$hd" "$(date)"; } > tmp && mv tmp file; cat file
old3
old1 Thu, Jul 25, 2019  4:28:44 PM
old2 Thu, Jul 25, 2019  4:28:46 PM

$ hd="$(head -1 file)"; { tail +2 file; printf '%s %s\n' "$hd" "$(date)"; } > tmp && mv tmp file; cat file
old1 Thu, Jul 25, 2019  4:28:44 PM
old2 Thu, Jul 25, 2019  4:28:46 PM
old3 Thu, Jul 25, 2019  4:28:48 PM

関連情報