shell - 为 IBMi IFS 上的目录中的每个文件递归搜索目录

标签 shell grep ibm-midrange ibm-ifs

我正在尝试写两个 (编辑: shell )脚本,我有一些困难。我将解释目的,然后提供脚本和当前输出。

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

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

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

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

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

我的测试文件夹结构是:

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 发行版上尝试这个,看看我是否得到不同的结果。

我很欣赏任何先进的见解。

最佳答案

介绍

这并不是一个真正的完整解决方案,因为我不是 100% 确定我理解你想要做什么。但是,以下内容包含一些解决方案,您可以将这些解决方案拼接在一起以完成您想要的操作。

创建测试工具

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

然后,您可以使用查找的 -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

像这样循环通常较慢,但如果您正在做一些复杂的事情,可能会为您提供所需的额外灵活性。天啊。

关于shell - 为 IBMi IFS 上的目录中的每个文件递归搜索目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27850595/

相关文章:

java - 如何使用运行时?

regex - 从许多文件中删除特定的(复杂的)行(sed?)

javascript - 使用javascript在浏览器中解析grep的结果

sql - 达到总和后停止 SQL 选择

sql-server - 列出可用库 - SQL Linked Server AS400

linux - 为什么 Linux 中的 rm 命令可以在几秒钟内删除文件/目录,而在 FTP 中删除却非常慢

linux - 脚本创建父目录的 tar,该目录将具有其子目录的单独 tar

linux - 在 unix/linux 中删除文件中最后一次出现的字符串

regex - Grep 某些字符

pdf - 将 PDF 添加到 AFP 输出