将文件路径转换为字符串

时间:2013-04-25 19:01:07

标签: bash shell

我在尝试找到用另一个字符串

替换目录路径中的字符串时遇到错误
sed: Error tryning to read from {directory_path}: It's a directory 

shell脚本

#!/bin/sh

R2K_SOURCE="source/"
R2K_PROCESSED="processed/"
R2K_TEMP_DIR=""

echo " Procesando archivos desde $R2K_SOURCE "

for file in $(find $R2K_SOURCE )
do
        if [ -d $file ]
        then
                R2K_TEMP_DIR=$( sed 's/"$R2K_SOURCE"/"$R2K_PROCESSED"/g' $file )
                echo "directorio $R2K_TEMP_DIR"
        else
#               some code executes
                :
        fi
done

# find $R2K_PROCCESED -type f -size -200c -delete

我理解这行中的错误

R2K_TEMP_DIR=$( sed 's/"$R2K_SOURCE"/"$R2K_PROCESSED"/g' $file )

但我不知道如何告诉sh将$ file变量视为字符串而不是目录对象。

2 个答案:

答案 0 :(得分:8)

如果你想要替换路径名的一部分,你可以回显路径名并将其带到sed over pipe。 此外,您必须通过将sed命令放入双引号而不是单引号来启用globbing,并为's'命令更改分隔符,如下所示:

R2K_TEMP_DIR=$(echo "$file" | sed "s:$R2K_SOURCE:$R2K_PROCESSED:g")

然后你就可以在's'命令中使用斜杠进行操作。

更新

更好的是删除无用的回声并使用“here is string”代替:

R2K_TEMP_DIR=$(sed "s:$R2K_SOURCE:$R2K_PROCESSED:g" <<< "$file")

答案 1 :(得分:3)

首先,不要使用:

for item in $(find ...)

因为您可能会重载命令行。此外,在$(...)中的进程完成之前,for循环无法启动。代替:

find ... | while read item

您还需要注意时髦的文件名。 for循环将咳嗽所有带有空格的文件。只要文件名称中只有一个空格而不是双重空格,find | while就可以正常工作。更好:

find ... -print0 | while read -d '' -r item

这将在文件名之间放置空值,read将在这些空值上中断。这样,可以毫无问题地读取包含空格,制表符,换行符或其他任何可能导致问题的文件。

你的上线是:

R2K_TEMP_DIR=$( sed 's/"$R2K_SOURCE"/"$R2K_PROCESSED"/g' $file )

这是尝试做的是编辑您的$file这是一个目录。你想要做的是munge目录名称本身。因此,您必须将名称作为管道回显到sed

R2K_TEMP_DIR=$(echo $file | sed 's/"$R2K_SOURCE"/"$R2K_PROCESSED"/g')

但是,最好使用环境变量参数来过滤环境变量。

基本上,您有一个名为source/的目录,您要查找的所有文件都在该目录下。你只想改变:

 source/foo/bar

 processed/foo/bar

您可以执行类似$ {file#source /}的操作。 #表示这是左侧过滤器,它将删除与#之后的glob表达式匹配的最小量。检查bash的联机帮助页,然后查看参数扩展

这个,你可以做这样的事情:

#!/bin/sh

R2K_SOURCE="source/"
R2K_PROCESSED="processed/"
R2K_TEMP_DIR=""

echo " Procesando archivos desde $R2K_SOURCE "

find $R2K_SOURCE -print0 | while read -d '' -r file
do
    if [ -d $file ]
    then
        R2K_TEMP_DIR="processed/${file#source/}"
        echo "directorio $R2K_TEMP_DIR"
    else
#       some code executes
        :
    fi
done

R2K_TEMP_DIR="processed/${file#source/}"source/开头删除$file,您只需将processed/添加到其位置。

更好的是,它的效率更高。在原始脚本中,$(..)创建另一个shell进程来运行echo,然后在其中导出到另一个进程以运行sed。 (假设你使用loentar的解决方案)。您不再运行任何子进程。您的目录名称的整个修改是内部的。

顺便说一句,这也应该有效:

R2K_TEMP_DIR="$R2K_PROCESSED/${file#$R2K_SOURCE}"

我只是没有测试过。