Linux 如何在名称中包含空格的目录中搜索文件;找到“;?

Linux 如何在名称中包含空格的目录中搜索文件;找到“;?,linux,bash,shell,sed,find,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

如何使用
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

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

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

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

find-类型f-名称“**”


您可以指定路径,而不是
,您希望在其中查找符合条件的文件

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

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)
-print0

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

正如该男子所说,这将与
xargs
-0
选项相匹配。其他几个标准工具也有相同的选项。为了干净地处理包含空格的文件名,您可能必须重写这些工具周围的复杂管道


此外,请参阅以了解如何使用以0结尾的参数的for循环。

您的第一个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循环将文件名存储在数组中,然后使用
sort
uniq
在读取时使用
,从
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)
#/bin/bash
而IFS=read-rd''i;做
而IFS=read-rd''j;做
查找“/tmp/2/”-iname“$j.sh”-exec echo cp'{}'$i”\;

done从未对$(find…
中的i使用
,或者类似的方法,因为如您所见,对于包含空格的文件名,它将失败

使用
find…|而IFS=read-ri

很难说没有样本输入和预期输出,但类似的东西可能就是您所需要的:

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
选项,并将其传送到
xargs-0

,问题实际上不是
查找
而是
for
自“空格”起的循环作为项目之间的分隔符。您到底想在这里做什么?@skamazin我在某个目录中有一个.txt文件。我希望脚本搜索与.txt文件同名的文件,并将它们复制到带有.txt文件的目录中。我需要递归搜索。@SerjAntiquity“我希望脚本搜索与该.txt文件同名的文件,并将它们复制到与该.txt文件同名的目录中。”如果复制同名的文件(包括
.txt
ext),您将覆盖该文件。这是预期的行为吗?@Sylvain Leroux,不,我复制了一个同名但扩展名不同的文件(.sh)。缺少仅用于常规文件类型的筛选器。在您的示例中,目录类型文件不会被筛选。我希望脚本搜索与.txt同名的文件,并将它们复制到源为.txt的目录中