AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 703007
Accepted
Alex
Alex
Asked: 2022-05-19 03:09:12 +0800 CST2022-05-19 03:09:12 +0800 CST 2022-05-19 03:09:12 +0800 CST

如何正确使用 bash 函数的引号?

  • 772

我正在尝试在我的.bashrc文件中定义以下 bash 函数:

function myfind() {
    find $1 -not -path venv -not -path .tox -name "$2" | xargs grep -n "$3"
}

这不是我所期望的。当我使用该功能搜索文件中的文本时,例如

myfind . *.py test

它不返回任何东西。但是当我直接使用表达式时,即

find . -not -path venv -not -path .tox -name "*.py" | xargs grep -n "test"

它返回一些匹配项。

我已经尝试使用双引号,例如

function myfind() {
    find $1 -not -path venv -not -path .tox -name '"$2"' | xargs grep -n '"$3"'
}

或者

function myfind() {
    find $1 -not -path venv -not -path .tox -name "'$2'" | xargs grep -n "'$3'"
}

并试图逃避像

function myfind() {
    find $1 -not -path venv -not -path .tox -name \"$2\" | xargs grep -n \"$3\"
}

但这些似乎都不起作用。

如何修复这个 bash 函数,以便在参数周围“使用”引号?

bash quoting
  • 1 1 个回答
  • 247 Views

1 个回答

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2022-05-19T03:28:22+08:002022-05-19T03:28:22+08:00

    伊蒂姆:

    myfind() {
      find "$1" '(' -name venv -o -name .tox ')' -prune -o \
                -name "$2" -type f -exec grep -Hne "$3" -- {} +
    }
    

    接着:

    myfind . '*.py' test
    

    另请参阅为什么循环查找的输出是不好的做法?为什么调用类似xargs的输出find是错误的。

    您的方法的其他一些问题:

    • -path venv永远不会匹配任何东西作为-path正在考虑的文件的完整路径上的匹配,这将类似于<contents-of-$1>/subdir/file. 只有在调用的顶层myfind venv ...才会匹配。我假设您想忽略存储在名为venv. 虽然您可以使用! -path '*/venv/*'它,但首先告诉find不要进入这些目录比事后过滤掉其中的所有文件更有效(! -path '*/venv/*'如果文件路径在语言环境中不是有效文本,也会有问题) .

    • 使用myfind first *.py last,您要求外壳程序扩展*.py到当前目录中的匹配文件列表中,以构成 的倒数第二个参数myfind,而*.py您希望将其传递给myfindformyfind以将其传递给findafter的文字参数-name,因此需要引用该*字符,以便它不会被 shell 解释为通配符。在这里,我们用 if or 来引用整个内容*.py就足够了,因为其他 3 个字符('*.py'和)对于shell 来说并不是特殊的。'*'.py\*.py.py

      如果使用 zsh 而不是 bash,则可以alias myfind='noglob myfind'在myfind. 然后你就可以在myfind . *.py test不*.py被外壳扩展的情况下做到这一点。

    • 必须引用参数扩展以防止 split+glob ( "$1", not $1)。

    • 如果没有-H(GNU 扩展)如果find只找到一个文件,则grep不会打印其路径,因此您将不知道匹配项在哪里。对于grep不支持的实现,您可以作为额外参数-H传递: ./dev/null-exec grep -ne "$3" -- /dev/null {} +

    • 请参阅!与非标准等效的标准(或更短)-not。

    • 与grep -n "$3",如果$3以 开头-,它将被 视为一个选项grep。因此,-e "$3"相反,其中的内容$3作为参数传递给-e选项。有同样的问题find "$1",但不幸的是,没有标准的解决方法。find -- "$1"会阻止它的内容$1被视为以开头的选项,但它仍将被视为谓词,因此毫无意义。例如,一个名为or的目录也是一个问题。BSD可以做到这一点,但 GNU和大多数其他实现不支持它。利用find-!(findfind -f "$1"findfindmyfind ./-dir-starting-with-data- '*.py' pattern传递以破折号开头的目录。

    • 代码中唯一不是标准sh语法的是function name()函数定义语法。ksh 语法是function name {...;},Bourne 和标准bash语法是name() {...;}. 虽然bash也是function name() { ...; }偶然支持,但没有真正好的理由使用它。

    • 我已将 a 添加-type f到仅考虑的常规文件中,因为您可能不想grep 在设备文件或 fifos 中开始搜索,它会报告目录或套接字的错误。使用 GNU find,您可以将其替换为,-xtype f以便最终解析为常规文件的符号链接也被考虑在内。

    • 6

相关问题

  • 通过命令的标准输出以编程方式导出环境变量[重复]

  • 从文本文件传递变量的奇怪问题

  • 虽然行读取保持转义空间?

  • `tee` 和 `bash` 进程替换顺序

  • 运行一个非常慢的脚本直到它成功

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve