ファイル拡張子がある場合は削除

ファイル拡張子がある場合は削除

スクリプトに初めて触れました。一部のテキストファイルを含むディレクトリがあり、一部のテキストファイルには追加の拡張子()も含まれています(.xfr例:、、、)。file1.txtfile2.txt.xfrfile3.txtfile4.txt.xfr

bashスクリプトを作成してディレクトリを確認し、.xfrファイルに含まれている場合はファイル名を変更し(拡張子を削除)、結果に基づいてログエントリを作成します。

ファイルの名前を変更するスクリプトを書くことができますが、ifこの部分に関して問題が発生しています。これは有効な部分です:

#!/bin/bash

for file in ~/Test/Files/*.xfr
do
    mv "$file" "${file%.xfr}"
    echo "$file has been resent" > ~/Test/log.txt
done

追加するにはifこれがうまくいくと思いましたが、残念ながらそうではありません。

#!/bin/bash

if [[ ! -e ~/Test/Files/*.xfr ]]
then
    mv "$file" "${file%.xfr}"
    echo "$file has been renamed" > ~/Test/log.txt
else 
    echo "no files were renamed" ~/Test/log.txt
fi

どんな助けでも大変感謝します。

更新:ファイルパスの代わりに変数を使用するようにスクリプトが更新されました。

#!/bin/bash

PATH='/home/davrog/Test/Files'
LOG='/home/davrog/Test/log.txt'

for file in $PATH/*.xfr

do

if [ -e $PATH/$file ]
   then
     mv "$file" "${file%.xfr}"
     echo "$(date) $file has been resent"
   else
     echo "$(date) no files were stuck when check was run"
fi

done >>$LOG

これはmv関数を破壊するようです。ファイル名を現在の名前に変更し直すので疑います。他の投稿を見ると、mv関数が正しく見えますが、どのように解決するのかわかりません。助けてくれてありがとう。

答え1

最初のスクリプトを少し修正してください。

#!/bin/bash

for file in ~/Test/Files/*.xfr
do
    if [ ! -e "$file" ]; then
        echo 'no files were renamed'
        break
    fi

    mv "$file" "${file%.xfr}"
    echo "$file has been renamed" 
done > ~/Test/log.txt

私はここで2つのことをしています。

  1. doneログファイルにリダイレクトすると、ループするたびにログファイルが切り捨てられ、ループ内のすべてのstdoutをリダイレクトするように最後に移動しました。

  2. パターンがファイル名と一致しない場合、デフォルトでは拡張されていません。テストによってこれを検出し-e、特別なメッセージを出力します。その後、breakループを終了します。

選択する:

#!/bin/bash

for file in "$HOME/Test/Files"/*.xfr
do
    if [ -e "$file" ]; then
        mv "$file" "${file%.xfr}"
        printf '%s has been renamed\n' "$file"
    else
        echo 'no files were renamed'
    fi   
done >"$HOME/Test/log.txt"

ここでは流れを少し変更し、$HOMEチルダの代わりに使用しました(IMHOはスクリプトでよりよく見えます)。私はまた、変数データを出力するのに通常より安全なので、printf代わりに使用しますecho(例:なぜprintfがechoより優れているのですか?")。

/bin/sh上記の両方の選択肢を実行する代わりに使用することもできます/bin/bash

より多くの「レポート」を作成するには、他のオプションがあります。

#!/bin/bash

shopt -s nullglob

xfr_files=( "$HOME/Test/Files"/*.xfr )

for file in "${xfr_files[@]}"; do
    mv "$file" "${file%.xfr}"
done

printf '%d files renamed\n' "${#xfr_files[@]}"
if [ "${#xfr_files[@]}" -gt 0 ]; then
    printf '\t%s\n' "${xfr_files[@]}"
fi

これはnullglobシェルオプションを設定し、bash一致するものがない場合はパターンが空白に拡張されます。次に、名前が変更されたファイルの数を記録し、その数が0より大きい場合は、タブのインデントとともにファイル名も一覧表示します。


更新された質問から、変数を使用してくださいPATH。これはシェルのユーティリティ検索パスを保持する変数なので、:--separated ディレクトリのリスト以外に設定すると、シェルがmv一般的に使用されている他のツールが見つからない場合があります。

通常、シェルスクリプトでは大文字の変数名を使用せず、代わりに小文字または大文字と小文字が混在する変数を使用します。これにより、シェルが使用できる重要な変数が誤って上書きされるのを防ぎます。

また[ -e $PATH/$file ]テストは[ -e "$file" ]パスが値に含まれているため読み取る必要があります$file。これは上記のコードでも私が使っているものです。すべての変数拡張を二重引用符で囲むことを忘れないでください!

答え2

prenameすでにインストールされている場合は、次のように実行できます。

prename 's/\.xfr$// and print "$_ resended\n"' ~/test/*  >  f.log

関連情報