shell find命令-仅获取基本名称-不使用基本名称命令/不使用printf

6psbrbz9  于 2023-02-05  发布在  Shell
关注(0)|答案(4)|浏览(190)

有没有办法在命令find中获取basename
需要的:

  • find /dir1 -type f -printf "%f\n"
  • find /dir1 -type f -exec basename {} \;

为什么呢?因为我需要继续使用found file,我基本上想要这样的东西:

find . -type f -exec find /home -type l -name "*{}*" \;

并且它使用./file1而不是file1作为-name的度量。
谢谢你的帮助:)

but5z9lq

but5z9lq1#

如果你有Bash 4.3或更高版本,试试下面的Shellcheck-clean pure Bash代码:

#! /bin/bash -p

shopt -s dotglob globstar nullglob
for path in ./**; do
    [[ -L $path ]] && continue
    [[ -f $path ]] || continue
    base=${path##*/}
    for path2 in /home/**/*"$base"*; do
        [[ -L $path2 ]] && printf '%s\n' "$path2"
    done
done
  • shopt -s ...启用代码所需的一些Bash设置:
  • dotglob允许全局匹配以.开始的文件和目录。默认情况下,find显示此类文件。
  • globstar支持使用**通过目录树递归地匹配路径。globstar是在Bash 4.0中引入的,但在Bash 4.3(2014)之前使用它是危险的,因为它在查找匹配时遵循符号链接。
  • nullglob使glob在没有匹配项时扩展为空(否则它们扩展为glob模式本身,这在程序中几乎没有用)。
  • 请参阅Removing part of a string(BashFAQ/100(How do I do string manipulation in bash?))了解${path##*/}的解释,这总是有效的,即使在$(basename "$path")不起作用的极少数情况下。
  • 请参阅Why is printf better than echo?的公认的、优秀的答案,以了解我为什么使用printf而不是echo来输出找到的路径。
  • 如果文件名中包含模式字符(?*[]\),则此解决方案可以正常工作。
nwlls2ji

nwlls2ji2#

生成一个shell,并从那里进行第二次调用

find /dir1 -type f -exec sh -c '
for p; do
  find /dir2 -type l -name "*${p##*/}*"
done' sh {} +

如果您的文件名称中可能包含特殊字符(如[?等),您可能需要像这样对它们进行转义以避免误报

find /dir1 -type f -exec sh -c '
for p; do
  esc=$(printf "%sx\n" "${p##*/}" | sed "s/[?*[\]/\\\&/g")
  esc=${esc%x}
  find /dir2 -type l -name "*$esc*"
done' sh {} +
kb5ga3dv

kb5ga3dv3#

你必须把它转发给另一个赋值器,在find中没有办法做到这一点。

find . -type f -printf '%f\0' |
    xargs -r0I{} find /home -type l -name '*{}*'

这回答了您关于尝试合并%f-exec find的功能的问题,并且基于您的示例,但是您的示例将原始文件名作为-name模式注入,因此请避免这种情况,并考虑其他解决方案。

xfb7svmp

xfb7svmp4#

只需生成一个bash shell:

find /dir1 -type f -exec bash -c '
    base=$(basename "$1")
    echo "$base"
    do_something_else "$base"
' bash {} \;

bash部分中的$1是由find过滤的每个文件。

相关问题