여러 파일의 이름을 바꾸고, 패턴 인스턴스를 하나만 남기고 모두 삭제하세요.

여러 파일의 이름을 바꾸고, 패턴 인스턴스를 하나만 남기고 모두 삭제하세요.

내 문제에 대한 간단한 해결책이 있어야 하는데 찾을 수 없습니다. 여러 폴더에 이름이 다음과 같은 여러 파일이 있습니다.무늬다음과 같이 연속해서 여러 번 반복합니다.

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

XYZ12다음 결과를 얻으려면 파일 이름에서 패턴 중 하나를 제외하고 모두 제거 해야 합니다 .

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

답변1

)찾다+이름(펄 rename) 솔루션:

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

두번째) 추가의세게 때리다+찾다+sed지원되지 않는 경우 prename다음 방법을 사용하십시오.

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

) 또한 sed다음을 사용하여 위의 bash 방법을 사용하지 않아도 됩니다.세게 때리다변수 대체:

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

답변2

아니면 시도해 볼 수도 있습니다:

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

바라보다주제

답변3

그리고 ksh93:

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

(행복하면 삭제 echo).

  • ~(N): 이 패턴에 대한 nullglob
  • @(...): 그룹화(일치하는 콘텐츠를 \1.
  • +(...): 하나 이상의 항목입니다 ....
  • 그래서 반복 이 *.log@(-+([^-]))\1*.log*이어집니다 .*.log-<non-hyphens>*.log*
  • ${f//pattern/replacement}: 패턴 교체 연산자.

따라서 다음 whatever.log-repeat-repeat-repeatwhatever.logwhatever.log-repeatwhatever.log.

당신은 또한 볼 수 있습니다거기쉘 글로브의 역참조 지원에 대한 추가 정보.

답변4

가장 쉬운 방법은 첫 번째 인스턴스를 삭제 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

편집하다: 사전에 모르신다면 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

관련 정보