web-dev-qa-db-ja.com

bashスクリプトで、変数整数を「sed -e」コマンドに渡すにはどうすればよいですか(18.04)

保持するファイルの量を設定する変数を使用して、ディレクトリ内の最も古いファイルを破棄するbashスクリプトを作成しようとしています。

私の最初のステップは、保持する10個の最新ファイルのセット数よりも古いファイルの数をカウントすることでした。

#!/bin/bash
# How many files in the current directory are older than the retained files
olderThanRetain=$(find -maxdepth 1 -type f | sort -r | sed -e '1,10d' | wc -l)
echo $olderThanRetain

正常に動作します。

しかし、保持するファイル数の変数を設定しようとすると:

#!/bin/bash
retain=10
# How many files in the current directory are older than the retained files
olderThanRetain=$(find -maxdepth 1 -type f | sort -r | sed -e "1,(( $retain ))d" | wc -l)
echo $olderThanRetain

しかし、これは私にエラーを与えます:

sed: -e expression #1, char 3: unexpected `,'

私は何を見逃しましたか?

1
Broadsworde

bashのコンマは特殊文字ではないため、この式を引用符で囲む必要はありません。次のように使用できます。

sed 1,${retain}d

奇妙なファイル名(改行を含むファイル名を想像してください)の問題を回避するには、0を行区切り文字として使用します。また、最後にアクセスした時間で逆にソートするために、そこで何をソートしているのかもよくわかりません。

find -maxdepth 1 -type f -printf "%A@ %p\0" | sort -zr | sed -z 's/[^ ]* //;'1,${retain}d

0を使用して、tr \\0 \\nを改行に変更できます。ゼロ区切りの行をカウントするには、tr -cd '\0' | wc -cを使用できます。 ファイル内のヌルで区切られたアイテムのカウント・U&L を参照してください。

説明

  • find -maxdepth 1 -type f -printf "%A@ %p\0" –サブディレクトリ(-type f)を検索せずに現在のディレクトリ内のすべてのファイル(-maxdepth 1)を検索し、"%A@ %p\0"(改行なし!)を出力します。
    %A@は、ファイルのアクセス時間( エポックからの秒数%pはファイル名で、\0null文字 、エスケープとディレクティブの完全なリストについては man find/EXPRESSION/ACTIONS/-printf を参照してください。
  • sort -zrzeroで区切られたデータをreverse順に並べ替えます
  • sed -z 'a;b –エントリの区切り文字としてsederoを使用して、すべてのエントリでz式aおよびbを実行します
    シェル専用の文字のみを引用する必要があります。 ここで引用する私の投稿 を参照してください。実際、この場合、引用符で囲む必要があるのは;(エスケープするか、単一引用符または二重引用符で)だけなので、sed -z s/[^ ]* //\;1,${retain}dも問題ありません。
    • s/[^ ]* //subスペース文字を含まない最初の文字列(=最初のスペース文字までのすべて)と、それに続く何も含まないスペース文字(=削除)
    • 1,${retain}d –最初の$retainエントリを削除します
1
dessert