![在文件中搜索字符串,如果找到,则检查同一目录中是否存在具有配对名称的文件](https://linux22.com/image/77384/%E5%9C%A8%E6%96%87%E4%BB%B6%E4%B8%AD%E6%90%9C%E7%B4%A2%E5%AD%97%E7%AC%A6%E4%B8%B2%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%89%BE%E5%88%B0%EF%BC%8C%E5%88%99%E6%A3%80%E6%9F%A5%E5%90%8C%E4%B8%80%E7%9B%AE%E5%BD%95%E4%B8%AD%E6%98%AF%E5%90%A6%E5%AD%98%E5%9C%A8%E5%85%B7%E6%9C%89%E9%85%8D%E5%AF%B9%E5%90%8D%E7%A7%B0%E7%9A%84%E6%96%87%E4%BB%B6.png)
我有许多具有相同结尾的不同文件.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 -r
和awk
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
部分,其余都一样)。