![在目录中递归复制文件名并添加路径前缀](https://linux22.com/image/71512/%E5%9C%A8%E7%9B%AE%E5%BD%95%E4%B8%AD%E9%80%92%E5%BD%92%E5%A4%8D%E5%88%B6%E6%96%87%E4%BB%B6%E5%90%8D%E5%B9%B6%E6%B7%BB%E5%8A%A0%E8%B7%AF%E5%BE%84%E5%89%8D%E7%BC%80.png)
我有一个工作目录:/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 到输出目录
- 解压标准输入