디렉터리에서 파일 이름을 반복적으로 복사하고 경로 접두어를 추가합니다.

디렉터리에서 파일 이름을 반복적으로 복사하고 경로 접두어를 추가합니다.

작업 디렉터리가 있습니다. /home/myusername/projectdir
작업 디렉터리에는 파일과 하위 디렉터리가 포함되어 있습니다. 하위 디렉터리의 깊이를 알 수 없습니다. 모든 파일을 동일한 출력 디렉터리에 넣고 기본 이름 앞에 하위 디렉터리 경로 ( 로 대체)를 추가
하고 싶습니다 .*.log/#

예:

/home/myusername/projectdir/file1.log                  -> /home/myusername/output/file1.log
/home/myusername/projectdir/subdir/file2.log           -> /home/myusername/output/#subdir#file2.log
/home/myusername/projectdir/subdir/subsubdir/file3.log -> /home/myusername/output/#subdir#subsubdir#file3.log

나는 이것을 시도했습니다 :

cd "$PROJECT_DIR"
CDIR=""
for x in **/*.log; do
    if [ "$CDIR" != "$PROJECT_DIR/${x%/*}" ]; then

        CDIR="$PROJECT_DIR/${x%/*}"
        SUBDIR="${x%/*}"
        PREFIX=${SUBDIR//'/'/'#'}

        cd "$CDIR"
        for FILENAME in *.log; do
            NEWNAME="#$PREFIX#$FILENAME"
            cp "$FILENAME" "$OUTPUT_DIR/$NEWNAME"
        done
    fi
done

어떻게 하면 더 우아하게 할 수 있을까요?

답변1

#!/bin/bash

newdir=/absolute/path/output
olddir=/absolute/path/project

find $olddir -name '*log' | while read line ; do
  if [ "$olddir" == "$( basename "$line" )" ] ; then
    #just move the file if there are no subdirectories
    mv "$line" "$newdir"
  else
    #1) replace old project dir with nothing 
    #2) replace all slashes with hashes
    #3) set new outdir as prefix
    #4) hope that there are no colons in the filenames
    prefix="$( sed -e "s:$olddir::" -e 's:/:#:g'  -e "s:^:$newdir/:" <<<"$( dirname "$line")" )"
    mv "$line" "$prefix"#"$( basename "$line" )"
  fi
done 

답변2

\0파일 이름의 합계는 구분된 문자열을 사용하여 처리할 수 있습니다 spaces.\n

cd "${PROJECT_DIR%/*}"
outdir="output"; mkdir -p "$outdir"
find "$PROJECT_DIR" -type f -name '*.log' -printf "%p\0${outdir}/%P\0" |
  awk 'BEGIN{FS="/";RS=ORS="\0"} 
       NR%2||NF==2 {print; next}
       {gsub("/","#"); sub("#","/#"); print}' |
    xargs -0 -n2 cp -T
  • mkdir -p대상 디렉터리를 만듭니다(이미 존재하면 오류가 발생하지 않습니다).
  • find\0구분된 파일 경로를 인쇄합니다 ( 디렉토리 경로가 %P없음을 의미 ). find$1
  • awk필요한 2개의 파일 경로를 cp두 개의 분리된 레코드로 생성합니다 \0.
  • xargs\0구분된 파일 경로를 한 번에 2개씩 읽고 다음으로 전달합니다.cp -T

tree시험 내용은 이렇습니다원천디렉토리`

projectdir
├── file0.txt
├── file1.log
└── subdir
    ├── file2.log
    └── subsubdir
        └── file3.log

2 directories, 4 files

이것은 tree그들 중 하나 입니다목적지디렉토리`

output
├── file1.log
├── #subdir#file2.log
└── #subdir#subsubdir#file3.log

0 directories, 3 files

답변3

(cd "$PROJECT_DIR" && find . -name "*.log") | tar -cf - -T - | (cd $OUTPUT_DIR && tar -xf -)

  • 프로젝트 디렉토리로 cd
  • 모든 로그 파일 찾기
  • tar의 로그 파일 목록을 표준 출력으로
  • 출력 디렉토리로 cd
  • 표준 입력 압축 풀기

관련 정보