grepとforを使用してファイル名を変更する

grepとforを使用してファイル名を変更する

拡張子が .txt、.data、.conf のファイルの名前を「.xml」に変更したいです。

hello.txt -> hello.xml

そのためには、ファイルに次の行も含まれている必要があります。<?xml version="1.0" encoding="UTF-8"?>

私が持っているのは次のものです:

for file in *
do
if [ $(grep -Rc '<?xml version="1.0" encoding="UTF-8"?>' --include ".txt" --include ".data" --include "*.conf") = true ]
then
rename extension to: .xml
fi
done

何か案は?

答え1

もし、あんたが必要それをやってみるgrepと、forおそらく次のような感じでしょうか?

grep -RlZ '<?xml version="1.0" encoding="UTF-8"?>' --include "*.txt" --include "*.data" --include "*.conf" | 
  xargs -0 sh -c 'for f; do echo mv -- "$f" "${f%.*}.xml"; done' sh

(echo正しく動作していることに満足したら、削除してください)。

  • grep -RlZ一致が見つかったファイル名のヌル区切りリストを出力します。

  • xargs -0ヌルで区切られたリストをsh -c

  • for fファイル名を位置パラメータとしてループする

whileまたは(ではなく の使用が許可されている場合)と追加のシェルスクリプトレットforをスキップして、xargs

grep -RlZ '<?xml version="1.0" encoding="UTF-8"?>' --include "*.txt" --include "*.data" --include "*.conf" | 
  while IFS= read -r -d '' f; do echo mv -- "$f" "${f%.*}.xml"; done

答え2

find . -type f \( -name "*.txt" -o -name "*.data" -o -name "*.conf" \) -exec sh -c '
    for file in "$@"; do
        if grep -qF "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" "$file"; then
            mv -- "$file" "${file%.*}.xml"
        fi
    done
' findshell {} +

findこのコンテキストでは、 の方が適切だと思います。 .txt.data、拡張子を持つ通常のファイルを再帰的に検索し、指定した文字列が各ファイルに存在するかどうかを確認します。存在する場合は、コマンドによって.conf拡張子が に変更されます。.xmlmv

コードが期待どおりに動作するかどうか不明な場合は、echobeforeを追加してmv動作を確認できます。

また、このスクリプトは POSIX 以外のユーティリティに依存しないことも述べておきます。

答え3

これを試すことができます:

for file in *.{txt,conf}; do 
  [[ $(grep "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" "$file") ]] && \
  mv "$file" "${file%.*}.xml" || echo "$file" " does not match"
done

答え4

使用方法bash:

shopt -s globstar dotglob nullglob extglob

string='<?xml version="1.0" encoding="UTF-8"?>'

for pathname in ./**/*.@(txt|data|conf); do
    if [[ -f $pathname ]] && grep -q -F "$string" "$pathname"; then
        mv -i "$pathname" "${pathname%.*}.xml"
    fi
done

まず、通常はデフォルトでは設定されないいくつかのシェル オプションを設定しますbash

  • globstarサブディレクトリに再帰的に一致するグロビング パターンを有効にします**
  • dotglobグロブパターンを隠し名前と一致させます。
  • nullglob一致しないパターンは展開されずに残るのではなく、完全に消えます。これにより、一致しない場合は、後のループがまったく実行されなくなります。
  • extglob拡張グロブパターンを有効にします。たとえば、@(txt|data|conf)括弧内の文字列の 1 つに一致します。

次に、候補名をループし、それぞれに指定された文字列があるかどうかをテストします。文字列が見つかった場合は、最後のドット文字の後のファイル名のサフィックスを に置き換えて、ファイルの名前を変更しますxml

関連情報