递归搜索 IBMi IFS 目录中的每个文件。

4
我正在尝试编写两个(更正:shell)脚本,但遇到了一些困难。我将解释其目的,然后提供脚本和当前输出。

1:获取目录中每个文件名的递归列表。然后搜索该目录中所有文件的内容以查找每个文件名。应返回特定文件名的每个出现的路径、文件名和行号。

2:获取目录中每个文件名的递归列表。然后搜索目录中所有文件的内容以查找每个文件名。应返回未在任何目录文件中找到的每个文件的路径和文件名。

我最终想使用脚本2在网站中查找并删除(实际上是将它们移动到另一个目录进行归档)未使用的文件。然后,我想使用脚本1查看每个出现并过滤任何重复的文件名。

我知道我可以使脚本2在运行时移动每个文件而不是作为第二步,但我想在执行任何操作之前确认脚本是否正确运行。确认其功能正确后,我会进行修改。

我目前正在IMBi系统的strqsh上进行测试。

我的测试文件夹结构如下:

scriptTest
---subDir1
------file4.txt
------file5.txt
------file6.txt
---subDir2
------file1.txt
------file7.txt
------file8.txt
------file9.txt
---file1.txt
---file2.txt
---file3.txt

我有一些文件中的文本包含现有文件名。
这是我的当前脚本1:
#!/bin/bash
files=`find /www/Test/htdocs/DLTest/scriptTest/ ! -type d -exec basename {} \;`
for i in $files
do
    grep -rin $i "/www/Test/htdocs/DLTest/scriptTest" >> testReport.txt;
done

目前它的功能是正确的,除了无法提供与匹配文件路径。grep 默认返回文件路径不是吗?
我离脚本2还有一点距离:
#!/bin/bash
files=`find /www/Test/htdocs/DLTest/scriptTest/ ! -type d`
for i in $files
do
    #split $i on '/' and store into an array
    IFS='/' read -a array <<< "$i"

    #get last element of the array 
    echo "${array[-1]}"

    #perform a grep similar to script 2 and store it into a variable
    filename="grep -rin $i "/www/Test/htdocs/DLTest/scriptTest" >> testReport.txt;"

    #Check if the variable has anything in it
    if [ $filename = "" ]   
            #if not then output $i for the full path of the current needle.
        then echo $i;
    fi
done

我不知道如何将字符串$i拆分成数组。我在第6行一直出现错误。
001-0059 Syntax error on line 6: token redirection not expected.

“我计划在实际的Linux发行版上尝试这个,看看是否会得到不同的结果。”
“提前感谢任何见解。”

1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - John Y
是的,对于脚本1,我只想要针的文件名。然后,我希望找到与该针匹配的完整路径名的文件。当我使用“-l”时,我只会得到匹配文件的文件名。当我不使用它时,我会得到匹配文件的文件名、行号和匹配的行。如何获取匹配文件的文件路径? - d.lanza38
“-L” 对于脚本2会有所帮助,因为我想找到非匹配项,但我认为它不会像“-l”一样输出路径。编辑 - 对于脚本2,我尝试仅在没有匹配项时报告针的完整路径。因此,“-L”可能不会有帮助,因为如果文件不存在,我将得到每个文件的输出。 - d.lanza38
1
我刚刚快速浏览了Qshell手册,发现在Qshell中-L的意义与“真正的”Unix衍生命令行 shell中完全不同,所以你就明白了。 - John Y
也许可以使用 PASE shell 而不是 QShell?在 PASE 中应该有更多与其他平台的标准匹配。 - user2338816
显示剩余2条评论
1个回答

1

介绍

这并不是一个完整的解决方案,因为我并不确定我完全理解你想要做什么。然而,以下内容包含了一些解决方案的 部分,你可能可以将它们拼凑在一起以达到你想要的目的。

创建测试工具

cd /tmp
mkdir -p scriptTest/subDir{1,2}
mkdir -p scriptTest/subDir1/file{4,5,6}.txt
mkdir -p scriptTest/subDir2/file{1,8,8}.txt
touch scriptTest/file{1,2,3}.txt

查找和删除重复项

在最一般的情况下,您可以使用find的-exec标志或Bash循环来运行grep或其他比较文件。但是,如果您只想删除重复项,则最好使用fdupesduff实用程序来识别(并可选地删除)具有重复内容的文件。

例如,假设测试语料库中所有的.txt文件都是零长度重复项,则考虑以下duff和fdupes示例

duff

Duff有更多的选项,但不会直接为您删除文件。您可能需要使用类似于duff -e0 * | xargs -0 rm的命令来删除重复项。要使用默认比较查找重复项:

$ duff -r scriptTest/
8 files in cluster 1 (0 bytes, digest da39a3ee5e6b4b0d3255bfef95601890afd80709)
scriptTest/file1.txt
scriptTest/file2.txt
scriptTest/file3.txt
scriptTest/subDir1/file4.txt
scriptTest/subDir1/file5.txt
scriptTest/subDir1/file6.txt
scriptTest/subDir2/file1.txt
scriptTest/subDir2/file8.txt

fdupes

这个实用工具可以直接以多种方式删除重复文件。其中一种方法是在你确认准备好后,调用fdupes . --delete --noprompt。然而,要找到重复文件的列表:

$ fdupes -R scriptTest/
scriptTest/subDir1/file4.txt            
scriptTest/subDir1/file5.txt
scriptTest/subDir1/file6.txt
scriptTest/subDir2/file1.txt
scriptTest/subDir2/file8.txt
scriptTest/file1.txt
scriptTest/file2.txt
scriptTest/file3.txt

获取包括非重复文件的所有文件列表
$ find scriptTest -name \*.txt
scriptTest/file1.txt
scriptTest/file2.txt
scriptTest/file3.txt
scriptTest/subDir1/file4.txt
scriptTest/subDir1/file5.txt
scriptTest/subDir1/file6.txt
scriptTest/subDir2/file1.txt
scriptTest/subDir2/file8.txt

您可以使用find的-exec {} +功能对每个文件进行操作,或者仅使用支持--recursive --files-with-matches标志的grep查找具有匹配内容的文件。

将查找结果作为数组传递给Bash循环

或者,如果您确定文件名中不会有空格,您也可以使用Bash数组将文件存储到变量中,以便在Bash for循环中进行迭代。例如:

files=$(find scriptTest -name \*.txt)
for file in "${files[@]}"; do
  : # do something with each "$file"
done

循环像这样通常较慢,但如果您正在进行复杂的操作,则可能为您提供所需的额外灵活性。YMMV。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接