在文件中搜索字符串,如果找到,则检查同一目录中是否存在具有配对名称的文件

在文件中搜索字符串,如果找到,则检查同一目录中是否存在具有配对名称的文件

我有许多具有相同结尾的不同文件.ft1,这些文件可能包含也可能不包含一个特定单词special。对于包含该单词的文件,我想检查.log该目录中是否存在另一个具有不同结尾的文件。

到目前为止我得到的是这样的:

find . -name "*.ft1" -exec grep -l "special" {} \; -execdir ls *log \;

ls但是,每次执行时都会出现错误:

ls: cannot access *log: No such file or directory

但是我知道该目录中有这样的文件。我还尝试转义星号,因此表达式变为-execdir ls \*log \;,但错误仍然存​​在。

我也看过类似的问题,但我目前看不到这如何帮助我解决我的问题。

我怎样才能让它正常工作?仅列出.log与找到的文件具有相同名称干的文件的解决方案的奖励积分.ft1

答案1

你的问题是你需要一个 shell 来解释 glob *.log。所以你需要-execdir调用一个shell。以下代码片段还将解决您的“同名词干”要求

find . -name "*.ft1" -exec grep -l "special" {} \; \
-execdir bash -c 'x=$1; x=${x%.txt}; ls "$x".log' bash {} \;

答案2

假设你的文件名中没有空格(并且你的心不打算使用find),这应该可以解决问题:

for file in *.ft1; do
   if grep -q 'special' ${file}; then
      ls -l ${file%.ft1}.log 2> /dev/null
   fi
done

它使用 bash 字符串操作来.ft1结束。我可以使用,但这也会匹配扩展名之前${file/ft1/log}恰好有的任何文件名。ft1

我重定向stderr到隐藏对不存在的文件的ls尝试。ls.log

答案3

使用grep -rawk

grep -rl 'special' *.ft1 | awk '{sub(/\.ft1$/,"");system("sh -c \"[ -f "$0".log ] && echo \\\"["$0".log\\\"] exists for ["$0".ft1]\"")}'

或者输出ls

grep -rl 'special' *.ft1 | awk '{sub(/\.ft1$/,"");system("sh -c \"[ -f "$0".log ] && ls "$0".log \"")}'

例子

% grep -rl 'special' *.ft1 | awk '{sub(/\.ft1$/,"");system("sh -c \"[ -f "$0".log ] && echo \\\"["$0".log\\\"] exists for ["$0".ft1]\"")}'
[one.log] exists for [one.ft1]

% grep -rl 'special' *.ft1 | awk '{sub(/\.ft1$/,"");system("sh -c \"[ -f "$0".log ] && ls "$0".log \"")}'
one.log

% ls -laog                        
total 100
drwxrwx--x   4  4096 Nov 13 22:03 .
drwxr-xr-x 272 86016 Nov 13 22:03 ..
drwxrwxr-x   2  4096 Nov 13 20:37 bar
drwxrwxr-x   2  4096 Nov 13 20:37 foo
-rw-rw-r--   1     8 Nov 13 21:55 one.ft1
-rw-rw-r--   1     0 Nov 13 21:54 one.log
-rw-rw-r--   1     0 Nov 13 21:54 three.ft1
-rw-rw-r--   1     0 Nov 13 21:54 two.ft1
-rw-rw-r--   1     0 Nov 13 21:54 two.log

% cat one.ft1
special

% cat two.ft1

答案4

这是一个zsh替代方案:

print -rl -- **/*.ft1(.e_'grep -q special $REPLY && REPLY=$REPLY:r.log && [[ -f $REPLY ]]'_)

这将递归搜索.ft1包含该字符串的文件并仅打印相应的.log文件。如果要打印.ft1包含该字符串的所有文件special 相应的.log文件(如果有)然后只需将grep's替换-q-l.
这是它的工作原理(这个有一个附加条件——grep部分,其余都一样)。

相关内容