具有如下所示的文件夹结构./all_files
-rwxrwxrwx reference_file.txt
drwxrwxrwx file1.txt
drwxrwxrwx file2.txt
drwxrwxrwx file3.txt
reference_file.txt的文件名如下所示
$cat reference_file.txt
file1.txt
file2.txt
file1.txt和file2.txt中的数据如下所示:
$cat file1.txt
step_1
step_2
step_3
现在,我必须从每个文件中采取特定步骤说出step2
注1:文件名必须出现在reference_file.txt
中注2:step2不是第二行:
注3:搜索应该递归执行。
我使用了以下脚本:
#!/bin/sh
for i in cat reference_file.txt;
do
find . -type f -name $i | grep -v 'FS*' | xargs grep -F 'step_2'
done<reference_file.txt
使用上面的代码后我没有输出。
# bash -x script.sh
+ for i in cat reference_file.txt
+ find . -type f -name **cat**
+ xargs grep -F 'step_2'
+ for i in cat **reference_file.txt**
+ find . -type f -name reference_file.txt
+ xargs grep -F 'step_2'
添加了新要求:
target = step_XX_2其中XX可以是任何内容,应该跳过搜索..所以希望输出将是.. step_ab_2 step_cd_2 step_ef_2
答案 0 :(得分:1)
我认为这是你想要实现的目标。请让我知道:
编辑:我以前的版本没有递归搜索。
进一步编辑:请注意,使用find
的进程替换意味着此脚本必须在bash
而不是sh
下运行。
进一步修改规范中的更改:请注意target
和-E
选项更改为grep
而不是-F
。
#!/bin/bash
target='step_.*?_?2'
while read -r name
do
# EDIT: exclude certain directories
if [[ $name == "old1" || $name == "old2" ]]
then
# do the next iteration of the loop
continue
fi
while read -r fname
do
if [[ $fname != FS* ]]
then
# Display the filename (grep -H is not in POSIX)
if out=$(grep -E "$target" "$fname")
then
echo "$fname: $out"
fi
fi
done < <(find . -type f -name "$name")
done < reference_file.txt
请注意,您的跟踪(bash -x
)使用了bash,但您的#!
行使用了sh
。它们是不同的 - 你应该与你正在使用的shell保持一致。
所以,我删除了xargs
,它读取字符串标准输入并使用字符串作为参数执行程序。由于我们已经拥有grep
的参数字符串,因此我们不需要它。
你的grep -v 'FS*'
可能没有达到预期效果。正则表达式FS*
表示“F后跟零个或多个S”。与shell模式匹配(globbing)不同。在我的解决方案中,我使用了FS*
,因为我使用的是shell,而不是grep
。
答案 1 :(得分:0)
我认为这个问题与this
重复您需要的是
#!/bin/sh
for i in `cat reference_file.txt`
do find . -type f -name $i | grep -v 'FS*' | xargs grep -F 'step_2'
done
请参阅反引号,并且不要两次读取文件reference_file.txt。