shell 脚本中的串联和'basename'的使用



我想从特定目录中读取所有文件名,然后通过在另一个目录中附加一些字符串来创建新文件。

例如>"A"、"B"、"C"在"日志"目录中 然后脚本应该在"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包含""作为最后一个字符,我无法连接字符串。

现在我不是在创建文件,只是打印所有名称。

那么,我如何从文件名中删除"",我的理解是否正确?

分析

脚本中有多个问题需要解决。 让我们一步一步来:

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

当然,回显是您计划执行的复制或移动操作的代理项。

编辑:。。。要删除对包含空格和通配字符的文件名的限制,请执行以下操作:

tempDir=./tmp/
logDir=./logs/
find "$logDir" -type f |
while IFS= read -r file
do
opFile="${tempDir}${file##*/}_tmp"
echo "$opFile"
done

对于包含换行符的文件名,它仍然会失败。如果要处理此问题,请使用find ... -print0 | xargs -0find ... -exec调查解决方案。

尝试以下操作。

#!/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

编辑:澄清

尝试这样的事情:

tempDir=./tmp/
logDir=./logs/
for file in $( find `echo $logDir` -type f )
do
name=`eval basename $file|tr -d "n"`_tmp
echo $name
done

如果您更改

name=eval basename $file

name=`eval basename $file`

然后 afterwads 名称包含您想要的内容。

相关内容

  • 没有找到相关文章

最新更新