何百ものファイルに深くネストされたフォルダ構造があります。各ファイルがある親フォルダの名前に基づいてファイルの名前を変更し、名前が変更されたファイルを定義済みの宛先フォルダに移動する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
もちろん、命名とパスは必要に応じて調整する必要があります。