이름이 수백 개의 파일로 깊게 중첩된 폴더 구조가 있습니다 . 각 파일이 있는 상위 폴더의 이름을 기반으로 파일 이름을 바꾼 다음 이름이 바뀐 파일을 정의된 대상 폴더로 이동하는 data.log
스크립트가 필요합니다 . data.log
원본 data.log
문서는 원래 위치에 남아 있어야 합니다.
예:
원본 파일이 그대로 유지 되도록 파일 이름을 변경한 다음 이동 /opt/slm/data/system/amd-823723/data.log
해야 합니다 .amd-823723
/opt/slm/output/
data.log
답변1
#!/bin/bash
OUTDIR=/opt/slm/output/
find /opt/slm/data -name data.log |
while read FILE; do
OUTFILE="$(basename "$(dirname "$FILE")")"
cp -p "$FILE" "$OUTDIR$OUTFILE"
done
답변2
그리고 zsh
:
autoload zmv # best in ~/.zshrc
zmv -n -C '**/(*)/data.log' '/opt/slm/output/$1'
만족스러우면 삭제합니다 -n
(테스트 실행용).
이것은-C
복사(그리고이름을 바꿔라/ mv
) 설명에 다음과 같이 나와 있지만이름을 바꿔라, 당신이 원하는 것 같아요복사파일을 output
디렉터리로 변경합니다.
답변3
사용 find -exec
:
find /opt/slm/data -name data.log -exec sh -c '
TARGET="/opt/slm/output/$(basename "$(dirname "$1")")";
cp -i "$1" "$TARGET"
' find-sh {} \;
답변4
이 솔루션은 공백이 없는 디렉터리 이름에만 작동합니다.
#!/bin/bash
targetDir=/opt/slm/output/
for myPath in `find /opt/slm/data/system |grep "data.log$"`
do
newName = `echo "$myPath" |awk 'BEGIN {FS="/"} /data.log/ {print $(NF-1)}'`
cp "$myPath" ${targetDir}"${newName}"
done
사실, 나를 포함하여 주어진 모든 솔루션은 정보 손실로 이어지기 때문에 잘못되었습니다.디렉토리의 경우:
a/a/data.log
a/data.log
b/a/data.log
모든 파일의 이름은 "a"이며 마지막 파일 b/a/data.log로 덮어쓰여집니다.
Python3의 예제 프로그램은 이 문제를 해결합니다.
import os
for x in (os.walk('/opt/slm/data/system')):
if x[2] == ['data.log']:
newName=x[0].replace('/','#').replace(' ','_')
os.system('cp "'+str(x[0])+'/data.log" /opt/slm/output/'+str(newName))
공백 대신 전체 경로와 _ 문자를 포함하는 이름을 만듭니다.
#opt#slm#data#system#dirname
물론 이름 지정과 경로는 필요에 맞게 조정해야 합니다.