gpt4 book ai didi

linux - Perl 一个衬垫可以在具有特殊字符的许多不同值上匹配路径中的精确单词

转载 作者:太空宇宙 更新时间:2023-11-04 04:17:42 24 4
gpt4 key购买 nike

如何精确匹配 find/tmp -type l -exec ls -l 输出中的 $TARGET_NAME 值?

 $ find /tmp -type l -exec ls -l 2>/dev/null {} +
lrwxrwxrwx 1 root root 24 Mar 18 12:41 /tmp/test/link -> /usr/admin/Collect_tests
lrwxrwxrwx 1 root root 43 Mar 18 12:41 /tmp/test/link1 -> /usr/admin/Collect_tests/Upload.CM@.www.com
lrwxrwxrwx 1 root root 68 Mar 18 12:41 /tmp/test/link2 -> /usr/admin/Collect_tests/Upload.CM@.www.com/Upload_Shema@@@.DATA.com
lrwxrwxrwx 1 root root 100 Mar 18 12:42 /tmp/test/link3 -> /usr/admin/Collect_tests/Upload.CM@.www.com/Upload_Shema@@@.DATA.com/List.files.emails.dummy*Printed
lrwxrwxrwx 1 root root 92 Mar 18 12:42 /tmp/test/link4 -> /usr/admin/Collect_tests/Upload.CM@.www.com/Upload_Shema@@@.DATA.com/List.files@emails.dummy

值的示例

 TARGET_NAME=Upload.CM@.www.com
TARGET_NAME=Upload_Shema@@@.DATA.com
TARGET_NAME=List.files.emails.dummy*Printed

目标:仅在 $TARGET_NAME 时打印:“链接名称”和“PATH”(最后一个字段)与最后一个字段中的单词完全匹配。

示例(当我们想要精确匹配时 - 而 TARGET_NAME=Upload_Shema@@@.DATA.com那么):

结果将显示如下

/tmp/test/link2 /usr/admin/Collect_tests/Upload.CM@.www.com/Upload_Shema@@@.DATA.com
/tmp/test/link3 /usr/admin/Collect_tests/Upload.CM@.www.com/Upload_Shema@@@.DATA.com/List.files.emails.dummy*Printed
/tmp/test/link4 /usr/admin/Collect_tests/Upload.CM@.www.com/Upload_Shema@@@.DATA.com/List.files@emails.dummy

有几个条件:

1) 只需要匹配最后一个字段(来自 ls -l 输出)

示例

      /usr/admin/Collect_tests/Upload.CM@.www.com

2) $TARGET_NAME 值应与整个单词匹配

完全匹配示例(同时TARGET_NAME=Upload.C​​M@.www.com):

    /usr/admin/Collect_tests/Upload.CM@.www.com

非完全匹配的示例:

    /usr/admin/Collect_tests/Upload.CM@.www.c

3) $TARGET_NAME 左侧必须存在反斜杠(“/”),$TARGET_NAME 右侧必须存在反斜杠或字符串结尾。

4) 需要转义特殊字符,如:“/”、“@ ”。 “*”等

5) 代码将成为 ksh 脚本的一部分(并且可以通过 Perl oneliner 或 AWK 或 ksh 等实现。)

示例

   find /tmp -type l -exec ls -l 2>/dev/null {} + | < Perl one liner .............. >    

最佳答案

正如在回答您的上一个问题(已删除)时提到的,解析 ls 输出非常不理想。可以使用 readlink 来代替。

find /tmp -type l -exec \
perl -e'
my $TARGET_NAME = shift;
for (@ARGV) {
my $p = readlink($_);
$p =~ m{(?:^|/)\Q$TARGET_NAME\E(?:/|\z)}
or next;
print("$_\t$p\n");
}
' "$TARGET_NAME" {} \;

或更有效地,

perl -MFile::Find::Rule -e'
my ($TARGET_NAME, $BASE) = @ARGV;
for (File::Find::Rule->symlink->in($BASE)) {
my $p = readlink($_);
$p =~ m{(?:^|/)\Q$TARGET_NAME\E(?:/|\z)}
or next;
print("$_\t$p\n");
}
' "$TARGET_NAME" /tmp

根据要求,这将匹配

TARGET_NAME
TARGET_NAME/
TARGET_NAME/x
.../TARGET_NAME
.../TARGET_NAME/
.../TARGET_NAME/x

但不是

TARGET_NAMEx/...
.../TARGET_NAMEx
.../TARGET_NAMEx/...
xTARGET_NAME/...
.../xTARGET_NAME
.../xTARGET_NAME/...
<小时/>

注意:如果您的 find 支持,请将 find ... -exec ...\; 更改为 find ... -exec ... +

关于linux - Perl 一个衬垫可以在具有特殊字符的许多不同值上匹配路径中的精确单词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15477126/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com