web-dev-qa-db-ja.com

複数のファイルの名前を変更し、パターンの1つのインスタンスを除くすべてを削除します

私の問題には簡単な解決策が必要ですが、私はそれを得ることができません。複数のフォルダに複数のファイルがあり、その名前には次のようにpatternが連続して複数回繰り返されています。

20170223_LibError.log-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-SAE066.log_compressed_at_2017-09-27_03-32-55.gz

1つを除いてすべて削除する必要がありますXYZ12ファイル名からのパターンの、次の結果を取得します。

20170223_LibError.log-XYZ12-SAE066.log_compressed_at_2017-09-27_03-32-55.gz
4
Godvil

afind + prename(Perl rename)ソリューション:

find . -type f -name "*-XYZ12-XYZ12-*.gz" -exec prename 's/(-XYZ12)(\1)+/$1/g' {} \;

b)追加bash + find + sedprenameがサポートされていない場合のアプローチ:

for f in $(find . -type f -name "*-XYZ12-XYZ12-*.gz"); do 
    p="${f%/*}"      # full path without basename (parent folders)   
    fn="${f##*/}"    # current filename (basename)
    new_fn=$(sed 's/\(-XYZ12\)\+/-XVZ12/' <<<"$fn")  # new file name
    mv "$f" "$p/$new_fn"
done

c)また、bashを使用するだけで、上記のbashアプローチでsedを使用しないようにすることができます。変数置換:

shopt -s extglob
for f in $(find . -type f -name "*-XYZ12-XYZ12-*.gz"); do 
    p="${f%/*}"      # full path without basename (parent folders)   
    fn="${f##*/}"    # current filename (basename)
    new_fn="${fn/+(-XYZ12)/-XVZ12}"  # new file name
    mv "$f" "$p/$new_fn"
done
6
RomanPerekhrest

または試すことができます

find . -type f -name "*-XYZ12*" | sed 'p;s/\(-XYZ12\)\{1,\}/-XYZ12/' | xargs -n2 mv

トピック を参照してください

2
Egor Vasilyev

_ksh93_の場合:

_for f in ~(N)*.log@(-+([^-]))\1*.log*; do
  echo mv -- "$f" "${f/@(*.log)@(-+([^-]))+(\2)/\1\2}"
done
_

(幸せなときにechoを削除します)。

  • ~(N):そのパターンのnullglob
  • @(...):グループ化(一致するものを_\1_として参照できるようにします。
  • +(...):1つ以上の_..._。
  • したがって、*.log@(-+([^-]))\1*.log*は_*.log_の後に_-<non-hyphens>_が繰り返され、その後に_*.log*_が続きます。
  • _${f//pattern/replacement}_:パターン置換演算子。

したがって、_whatever.log-repeat-repeat-repeatwhatever.log_を_whatever.log-repeatwhatever.log_に置き換えます。

シェルグロブでの後方参照サポートの詳細については、 there も参照してください。

2

最も簡単な方法は、最初にXYZ12-のすべてのインスタンスを削除し、最初の--XYZ12-に置き換えることです。

$ echo 20170223_LibError.log-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-SAE066.log_compressed_at_2017-09-27_03-32-55.gz | sed -E 's,XYZ12-,,g' | sed 's,-,-XYZ12-,'
20170223_LibError.log-XYZ12-SAE066.log_compressed_at_2017-09-27_03-32-55.gz

[〜#〜] edit [〜#〜]:事前にXYZ12がわからない場合は、cutを使用して抽出できます。たとえば、次のようなdo.shスクリプトを作成します。

#!/usr/bin/env sh

pattern=$(echo "$1" | cut -d- -f2)

echo "$1" | sed -E "s,$pattern-,,g" | sed "s,-,-$pattern-,"

使用法:

$ ./do.sh  20170223_LibError.log-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-SAE066.log_compressed_at_2017-09-27_03-32-55.gz
20170223_LibError.log-XYZ12-SAE066.log_compressed_at_2017-09-27_03-32-55.gz

そして別のパターンで:

$ ./do.sh  20170223_LibError.log-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-SAE066.log_compressed_at_2017-09-27_03-32-55.gz
20170223_LibError.log-NMNM-SAE066.log_compressed_at_2017-09-27_03-32-55.gz
1