我想从特定目录中读取所有文件名,然后通过在另一个目录中附加一些字符串来创建带有这些名称的新文件。
例如> 'A','B','C'位于'logs'目录中 那么脚本应该在'tmp'目录中创建'A_tmp','B_tmp','C_tmp'
我正在使用的是 -
tempDir=./tmp/
logDir=./logs/
for file in $( find `echo $logDir` -type f )
do
name=eval basename $file
echo $name
name=$(echo $name | sed 's/.$//')
echo $tempDir
opFile=$tempDir$name
echo $opFile
done
但我理解的是,$ file包含'\ n'作为最后一个字符,我无法连接字符串。
现在我不创建文件,只打印所有名称。
那么,我如何从文件名中删除'\ n',我的理解是否正确?
答案 0 :(得分:5)
您的脚本中有许多问题需要解决。让我们一步一步来看:
tempDir=./tmp/
logDir=./logs/
for file in $( find `echo $logDir` -type f )
此方案假设文件名中没有空格(这不是一个不寻常的限制;避免名称中的空格问题相对棘手)。此外,不需要echo
;只写:
for file in $(find "$logDir" -type f)
继续:
do
name=eval basename $file
这将运行basename
命令,环境变量name
设置为值eval
,参数$file
。你需要的是:
name=$(basename "$file")
其中双引号并非严格必要,因为名称不能包含空格(但引用所有文件名并不是一个坏习惯,因为有时名称确实包含空格)。
echo $name
这会回显空行,因为未设置名称。
name=$(echo $name | sed 's/.$//')
如果设置了名称,则会删除最后一个字符,但如果名称为A
,则您没有任何内容。
echo $tempDir
opFile=$tempDir$name
echo $opFile
done
给予或采用双引号以及您未将_tmp
后缀添加到opFile
这一事实,其余部分没有任何问题。
将更改放在一起,最终得到:
tempDir=./tmp/
logDir=./logs/
for file in $(find "$logDir" -type f)
do
name=$(basename "$file")
echo "$name" # Debug only
echo "$tempDir" # Debug only
opFile="$tempDir${name}_tmp"
echo "$opFile"
done
显示所有中间结果。你可以很好地将其压缩到:
tempDir=./tmp/
logDir=./logs/
for file in $(find "$logDir" -type f)
do
opFile="$tempDir"$(basename "$file")"_tmp"
echo "$opFile"
done
或者,使用双引号的简单组合,因为名称不包含空格:
tempDir=./tmp/
logDir=./logs/
for file in $(find "$logDir" -type f)
do
opFile="$tempDir$(basename $file)_tmp"
echo "$opFile"
done
当然,echo是作为您计划执行的复制或移动操作的代理。
编辑:...并删除对包含空格和通配符的文件名的限制,请将其命名为:
tempDir=./tmp/
logDir=./logs/
find "$logDir" -type f |
while IFS= read -r file
do
opFile="${tempDir}${file##*/}_tmp"
echo "$opFile"
done
包含换行符的文件名仍然会失败。如果您想处理该问题,请使用find ... -print0 | xargs -0
或find ... -exec
调查解决方案。
答案 1 :(得分:2)
请尝试以下操作。
#!/bin/sh
tmpDir=./tmp/
logDir=./logs/
# list all files in log directory, pipe into a loop that reads each path line
# by line..
# Also note that there is no newline in this case since it is swallowed by 'read'.
find $logDir -type f | while read path; do
# get the basename of the path
name=`basename $path`
# copy the found file to the temporary directory.
dest="$tmpDir/${name}_tmp"
echo $dest
done
Shell脚本能够在语句中轻松地连接字符串,如 $ tmpDir / $ {name} _tmp 所示,不需要替换输出,因为read吞下任何换行符。
查找...而阅读是一个非常有用的构造,当您想要读取多行时,它甚至适用于文件。
while read line; do
echo $line
done < filename.txt
编辑:澄清
答案 2 :(得分:1)
尝试这样的事情:
tempDir=./tmp/
logDir=./logs/
for file in $( find `echo $logDir` -type f )
do
name=`eval basename $file|tr -d "\n"`_tmp
echo $name
done
答案 3 :(得分:0)
如果你改变了
name=eval basename $file
到
name=`eval basename $file`
然后后面的名字包含你想要的东西。