Linux

遞歸地在目錄中復製文件名並添加路徑前綴

  • August 24, 2015

我有一個工作目錄:/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*一次讀取\02 個 -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 

引用自:https://unix.stackexchange.com/questions/224924