Linux
遞歸地在目錄中復製文件名並添加路徑前綴
我有一個工作目錄:
/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
我怎樣才能更優雅地做到這一點?
通過使用
\0
-delimited 字元串,這可以處理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
-delimited 文件路徑(%P
表示沒有find
的$1
目錄路徑)。- *
awk
*創建 , 所需的 2 個文件路徑cp
作為兩個\0
分隔記錄。- *
xargs
*一次讀取\0
2 個 -delimited 文件路徑,並將它們傳遞給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
#!/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