linux - Perl oneliner to match exact word in a path on many different values with special characters -
how match $target_name value find /tmp -type l -exec ls -l output?
$ 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
examples of values
target_name=upload.cm@.www.com target_name=upload_shema@@@.data.com target_name=list.files.emails.dummy*printed
target: print: "link name" , "path" (last field ) if $target_name match word in last field.
example (when want match exact - while target_name=upload_shema@@@.data.com then):
the results display following
/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
there few conditions:
1) need match last field (from ls -l
output)
example
/usr/admin/collect_tests/upload.cm@.www.com
2) $target_name value should match whole word
example of full match ( while target_name=upload.cm@.www.com ):
/usr/admin/collect_tests/upload.cm@.www.com
example of non-full match:
/usr/admin/collect_tests/upload.cm@.www.c
3) backslash ("/") must exist on left side of $target_name, , backslash or end of string must found on right of $target_name.
4) need escape special characters as: " / " , " @ " . " * " , etc
5) code part of ksh script (and beimplemented perl oneliner or awk or ksh etc .. )
example
find /tmp -type l -exec ls -l 2>/dev/null {} + | < perl 1 liner .............. >
as mentioned in response last question (since deleted), parsing ls
output suboptimal. readlink
can used instead.
find /tmp -type l -exec \ perl -e' $target_name = shift; (@argv) { $p = readlink($_); $p =~ m{(?:^|/)\q$target_name\e(?:/|\z)} or next; print("$_\t$p\n"); } ' "$target_name" {} \;
or more efficiently,
perl -mfile::find::rule -e' ($target_name, $base) = @argv; (file::find::rule->symlink->in($base)) { $p = readlink($_); $p =~ m{(?:^|/)\q$target_name\e(?:/|\z)} or next; print("$_\t$p\n"); } ' "$target_name" /tmp
as requested, match
target_name target_name/ target_name/x .../target_name .../target_name/ .../target_name/x
but not
target_namex/... .../target_namex .../target_namex/... xtarget_name/... .../xtarget_name .../xtarget_name/...
note: change find ... -exec ... \;
find ... -exec ... +
if find
supports it.
Comments
Post a Comment