首页 > 解决方案 > 在单个命令行中执行 grep 和 sed

问题描述

我写了一个带有两个数组的 perl 脚本。我的第一个数组包含一个名字列表,我的第二个数组包含一个名字列表,我想用这些名字替换名字。

这是一个快速而肮脏的脚本,我只是为了完成一些事情而编写,这样我就不必做手动工作。这不是我专注于看起来“干净”或超级高效的事情。出于这个原因,我正在利用system很多。

我正在使用的示例目录如下所示:

/myDir/Names/John/ 包含文件 John.log、John.txt、RandomFile.html

约翰日志

John is an engineer.
Jack and John are friends.

约翰.txt

John is 48 years old. 

其中 John 是我的第一个数组中的一个元素。例如,我希望能够将 John 替换为我的第二个数组 IN FILES THAT CONTAIN JOHN IN THE FILE NAME 中的 Mary。我希望该数组的元素更改为下一个数组中的相应元素编号。这是我想出的:

#!/usr/bin/perl
use strict;
use warnings;

my @firstnames = (John, Jack, Jill);
my @secondnames = (Mary, Nick, Joseph);

foreach my $old (@firstnames){
    foreach my $new (@secondnames){
         system("grep -rl $old /myDir/Names/$old/ | xargs sed -i 's/$old/$new/g' $old.* ");
        system("rename '$old' '$new' /myDir/Names/$old.*");
     }
}

Grep 似乎工作正常,重命名和 Sed 不是因为 '.*'。问题是我在哪里$old.*。它适当地将 $old 替换为数组中的正确元素,但它会查找名为John.*,的文件Jack.*Jill.*而不是读取.*为任何文件扩展名。显然,我不完全理解 sed 是如何工作的。我想要一些关于如何对包含$old任何文件扩展名的所有文件执行 sed 命令的帮助,因为目录中可能有多个文件具有相同的名称和不同的扩展名。我使用任何扩展名指定名字的原因是因为该文件可能包含RandomFile.html我上面列出的内容,并且我只想要包含$old扩展名之前的文件。

这是我想要的输出,其中文件名以及在文本中找到的单词将被第二个数组中的相应元素替换:

玛丽.log

Mary is an engineer.
Jack and Mary are friends.

玛丽.txt

Mary is 48 years old. 

注意:文件中的单词与它们所在的文件的名称匹配,与它们所在的目录的名称匹配。这就是这些目录及其文件的模式。

如果有任何不清楚的地方请告诉我,我会编辑我的帖子。

标签: arrayslinuxperl

解决方案


我遇到了无法完全追踪的 grep 问题,所以我find改用它似乎可以解决问题。这是我现在正在使用的,效果很好:

find ./$old -name "$old.*" -exec gsed -i -e "s/$old/$new/Ig" {} +

另一个需要注意的与问题中的问题没有特别相关的重要问题是我错误地使用了foreach循环。为了匹配数组中的每个元素,您必须遍历数组的大小。

#!/usr/bin/perl
use strict;
use warnings;

my $i = scalar @firstnames;
for ($i=0; $i < @firstnames; $i++){
.......
 }

推荐阅读