入力ファイルからトークンを読み取り、そこに記載されているファイルを削除する方法

入力ファイルからトークンを読み取り、そこに記載されているファイルを削除する方法

Folder と File_Prefix を含む構成を使用してファイルを削除するスクリプトを作成しています。

  • これは設定ファイルになります: config.txt

    /local/FolderA,App
    /local/FolderB,Log
    /local/FolderC,File
    
  • これが私のスクリプトです:

    file="local/config.txt"
    while IFS="," read -r folder prefix;
    do
        find %s -name %s* -type f -exec rm {} \ "$folder" "$prefix";
    done < "$file"
    

IFSしかし、正常に動作していません。トラブルシューティングを手伝っていただけますか?コマンドから値を割り当てるのに問題があります。

答え1

設定ファイルに改行やカンマが埋め込まれたフィールドが含まれていないこと、および指定されたディレクトリ内の指定されたファイル名プレフィックスを持つすべてのファイルを削除することを前提としています (つまり、再帰的に削除しません)。

#!/bin/sh

while IFS=, read -r directory prefix; do
    rm -- "$directory/$prefix"*
done <config.txt

これは、各行の最初のカンマ区切りフィールドを変数に読み込みdirectory、行の残りを変数に読み込みますprefix。その後、これらを使用してファイルを削除します。(`--` (二重ダッシュ) 引数はどこに記載されていますか?--についての説明は

削除を再帰的に実行する必要がある場合は、記載されている各ディレクトリ パスの下で次の手順を実行します。

#!/bin/sh

while IFS=, read -r directory prefix; do
    find "$directory" -name "$prefix*" -exec rm {} +
done <config.txt

これら 2 つの違いは、再帰的に検索することとは別に、コマンド内のグロブ パターンであるかのように使用されるfindことです。$prefixfind

*を引用符で囲む必要があることに注意してください。そうしないfindと、シェルはそれを現在のディレクトリ内の一致する名前に展開しません。*引用なし上記の最初のループ内で使用するとrm、シェルはそれをすべての一致する名前に展開します。

もし、あんたがしない削除を再帰的に実行したいが、生成されたパターンに一致するファイルが多すぎて、最初のループで「引数リストが長すぎます」というエラーが発生する場合は、追加の内部ループを実行する必要があるかもしれません。

#!/bin/sh

while IFS=, read -r directory prefix; do
    for pathname in "$directory/$prefix"*; do
        rm -- "$pathname"
    done
done <config.txt

または、findトップレベルの検索パスに限定して使用する。

#!/bin/sh

while IFS=, read -r directory prefix; do
    find "$directory" ! -path "$directory" -prune -name "$prefix*" -exec rm {} +
done <config.txt

答え2

xargs を使用して、config.txt ファイルからコマンド ラインの sh 実行可能ファイルにファイル パスを渡します。

< config.txt xargs -rd'\n' sh -c '
for arg do
 find "${arg%,*}" \
    -name "${arg##*,}*" \
    -type f \
    -exec rm -f {} + ;
done
' xargs-sh

関連情報