![遍历、复制和转换文件名](https://linux22.com/image/62604/%E9%81%8D%E5%8E%86%E3%80%81%E5%A4%8D%E5%88%B6%E5%92%8C%E8%BD%AC%E6%8D%A2%E6%96%87%E4%BB%B6%E5%90%8D.png)
我的问题:我需要复制日志文件,所有日志文件都具有相同的名称,但存储在子目录的 1 层深处,并更改它们的名称。
我正在从名为 Logfiles 的文件夹中复制,其中包含一堆文件夹:
W3SVC114
,W3SVC1507562355
,W3SVC350179472
, ETC。
每个文件夹都将包含一个名为: 的文件u_ex[YYMMDD].log
,其中 [YYMMDD] 是日期戳。
我需要将所有这些日志文件放在一个文件夹中。由于所有名称都是相同的,我想将目录名称添加到结果文件名中,例如:
W3SVC1507562355/u_ex150407.log
变成W3SVC1507562355_u_ex150407.log
我如何让所有这些发生?我有点超出我的深度......:-/
答案1
兹什带有一个名为zmv
这使得移动或复制文件以及对名称应用基于模式的转换变得容易。将其放入您的.zshrc
(或在命令行上运行它):
autoload -U zmv
alias zcp='zmv -C'
alias zln='zmv -L'
然后,可以使用以下任何等效命令来完成重命名复制:
zcp 'Logfiles/(*)/(*.log)' 'destination_directory/${1}_$2'
zcp -w 'Logfiles/*/*.log' 'destination_directory/${1}_${2}.log'
zcp -W 'Logfiles/*/*.log' 'destination_directory/*_*.log'
如果您不想安装 zsh,您可以在任何 shell 中使用循环执行相同的操作:
cd Logfiles
for x in */*.log; do
cp -- "$x" "destination_directory/${x%/*}_${x##*/}"
done
答案2
您可以使用以下脚本将文件从一个位置复制到另一个位置并修改名称。
注意:在以下脚本中,我们硬编码了两个值。
/日志文件/:- 将日志文件名称更改为必须从中复制文件的有效文件夹名称。
/tmp/:- 这是您要在其下复制文件的目录。根据您的要求更改此目录名称。
#!/bin/bash find /Logfiles/ -maxdepth 1 -type f | #find all files located under folder Logfiles with maxdepth one. while read FILEDIR #Read all files line by line. do DIR="${FILEDIR%/*}" # Get the folder name its inside # echo $DIR FILE="${FILEDIR/*\/}" # Get the plain file name. # echo $FILE NEWFILE="${DIR}"_"${FILE}" # set new filename. # echo $NEWFILE echo -e "coping $FILE from $DIR in /tmp with name $NEWFILE \n" cp $DIR/$FILE /tmp/$NEWFILE #copy file from old location to new location with modified name. done
答案3
和pax
:
pax -'rws|/|_|' -- */u_ex150407.log target/dir
pax
是 POSIX 指定的标准文件归档器。不幸的是 - 尽管这是必需的Linux 标准库并且已经有一些相同的版本增量 - 无论出于何种原因,许多发行版都没有按照这两个标准的要求将其与默认安装一起打包。我认为这很遗憾,因为它是一个非常通用的工具。
上面我告诉pax
进入-r
ead 和-w
rite 模式(翻译为副本)并且 - 在命名其输出文件时 --s
用.您基本上可以在那里执行标准 BRE 语法/
_
sed
(除了此处允许左侧的文字换行符之外),但在这种情况下不需要任何详细说明。
不管怎样,这就是你所需要的。如果您由于某种原因没有安装它,我建议您安装它并尝试一下pax
。
答案4
简单的 POSIX shell 答案:
#!/bin/sh
for i in */*.log
do mv "$i" "${i//\//_}"
done
移动*/*.log
与相同名称匹配的每个文件,并/
替换为_
.