如何在名称中包含空格的目录中搜索文件,使用" find"?

时间:2014-08-18 12:15:32

标签: linux bash shell sed find

如何使用find在名称中包含空格的目录中搜索文件? 我用脚本

#!/bin/bash
for i in `find "/tmp/1/" -iname "*.txt" | sed 's/[0-9A-Za-z]*\.txt//g'`
do
    for j in `ls "$i" | grep sh | sed 's/\.txt//g'`
    do
        find "/tmp/2/" -iname "$j.sh" -exec cp {} "$i" \;
    done
done

但是不处理名称中包含空格的文件和目录?

6 个答案:

答案 0 :(得分:2)

这将获取所有包含空格的文件

$ls
more space  nospace  stillnospace  this is space
$find -type f -name "* *"
./this is space
./more space

答案 1 :(得分:1)

我不知道如何实现目标。但是考虑到实际解决方案,问题不在于find,而在于for循环,因为“空格”被视为项目之间的分隔符。

对于这些情况,

find有一个有用的选项:

  来自man find

     

<强> -print0

     

真;在标准输出上打印完整文件名,后跟空字符       (而不是-print使用的换行符)。这允许文件名     包含要正确解释的换行符或其他类型的空格     由处理查找输出的程序。此选项对应于-0     xargs的选项。

正如该男子所说,这将与-0的{​​{1}}选项相匹配。其他几种标准工具也有相同的选择。您可能必须围绕这些工具重写复杂管道,以便干净地处理包含空格的文件名。

此外,请参阅bash "for in" looping on null delimited string variable以了解如何使用带有0终止参数的 for loop

答案 2 :(得分:0)

这样做

find . -type f -name "* *"

您可以指定路径,而不是.,而是要在哪里找到符合条件的文件

答案 3 :(得分:0)

你的第一个for循环是:

for i in `find "/tmp/1" -iname "*.txt" | sed 's/[0-9A-Za-z]*\.txt//g'`

如果我理解正确,它会查找/tmp/1目录中的所有文本文件,然后尝试使用sed命令删除文件名吗?这将导致内部for循环多次处理具有多个.txt文件的单个目录。这就是你想要的吗?

您可以使用dirname而不是使用sed来删除文件名。此外,稍后,您使用sed摆脱扩展。您可以使用basename

for i in `find "/tmp/1" -iname "*.txt"` ; do
  path=$(dirname "$i")
  for j in `ls $path | grep POD` ; do
    file=$(basename "$j" .txt)
    # Do what ever you want with the file

这并不能解决多次处理单个目录的问题,但如果这对您来说是个问题,您可以使用上面的for循环将文件名存储在数组中,然后删除重复项使用sortuniq

答案 4 :(得分:0)

使用来自while read的空分隔路径名输出的find循环:

#!/bin/bash
while IFS= read -rd '' i; do
    while IFS= read -rd '' j; do
        find "/tmp/2/" -iname "$j.sh" -exec echo cp '{}' "$i" \;
    done <(exec find "$i" -maxdepth 1 -mindepth 1 -name '*POD*' -not -name '*.txt' -printf '%f\0')
done <(exec find /tmp/1 -iname '*.txt' -not -iname '[0-9A-Za-z]*.txt' -print0)

答案 5 :(得分:0)

从未使用for i in $(find...)或类似内容,因为您看到的包含空格的文件名将失败。

改为使用find ... | while IFS= read -r i

如果没有样本输入和预期输出,很难说,但这样的事情可能就是你所需要的:

find "/tmp/1/" -iname "*.txt" |
while IFS= read -r i
do
    i="${i%%[0-9A-Za-z]*\.txt}"
    for j in "$i"/*sh*
    do
        j="${j%%\.txt}"
        find "/tmp/2/" -iname "$j.sh" -exec cp {} "$i" \;
    done
done

对于包含换行符的文件名,上述内容仍然会失败。如果您遇到这种情况但无法修复文件名,请查看-print0的{​​{1}}选项,并将其汇总到find