【问题标题】:Why does my find command not work?为什么我的 find 命令不起作用?
【发布时间】:2015-04-29 00:21:36
【问题描述】:

对于我们的 IOS 项目,我想合并旧式的 pragma 行,例如

#pragma mark -
#pragma mark Getters

像单行一样

#pragma mark - Getters

在网上做了一些研究,想出了如下终端命令:

find . -type f -exec awk '{if (sub(/#pragma mark -$/,"#pragma mark -")) printf "%s", $0; else print $0}' {} > {} \;

这是合并这两行的第一个命令。然后我会使用另一个删除多余的#pragma mark - 字符。但是,上述命令不会终止。它根本不会改变任何东西。

【问题讨论】:

  • 你不能awk file > file(你使用什么命令无关紧要)终端立即截断输出文件,所以你的命令永远不会看到任何文件内容。跨度>
  • @EtanReisner 感谢您的提示。由于我是 bash 魔法的新手,我不知道如何规避这个问题。
  • 您对一个文件进行操作并输出到另一个文件,然后将新文件移到旧文件上。
  • 使用 xargs 代替 exec

标签: bash replace awk terminal


【解决方案1】:

当您按下回车键时,shell 首先处理所有重定向,在本例中为 > {}。这发生在 shell 为find 创建进程之前,因为它需要将find 进程的输出连接到{}。这意味着您应该在当前文件夹中找到一个文件{}

我认为在这种情况下你最好使用循环:

find . -type f -print0 | while IFS= read -r -d $'\0' file
do
   awk ... "$file" > "$file"
done

但有一个问题:shell 将首先进行重定向。这意味着它将创建一个empty $file 作为awk 的输出,然后启动awk,然后开始读取所述空文件。实现相同目标的更简单方法是echo -n > "$file"

所以你真的需要写入一个临时文件然后重命名:

find . -type f -print0 | while IFS= read -r -d $'\0' file
do
   awk ... "$file" > "$file.tmp" && mv "$file.tmp" "$file"
done

并确保在运行命令之前备份所有内容,因为它可能会出错。例如,如果您的版本控制中有一个隐藏文件夹,find 将进入该文件夹,然后awk 将销毁一些重要的位。

PS:如果您使用 IDE,请启用正则表达式并搜索 #pragma mark -\n#pragma mark Getters。现在您可以将这两行替换为一行,您的 IDE 将确保 95% 的字符串不会在您不希望发生的地方被替换。

【讨论】:

【解决方案2】:

如果你的awk版本>=4.1.0,你可以这样做

find . -type f -exec awk -i inplace '{if (sub(/#pragma mark -$/,"#pragma mark -")) printf "%s", $0; else print $0}' {} \;

【讨论】:

  • 有用的选项,但是您从问题中复制的 awk 命令不正确,find 至少没有转义花括号也不正确。
【解决方案3】:

这应该可行:

#!/usr/bin/python
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

import re
import sys

array = [] pragmas = [] with open("my.file", "r") as ins:
    i = 0
    lastPragmaLine = 0
    for line in ins:
        m = re.search(r'^\s*[#]\s*pragma\s+mark\s+(.*\S)\s*$', line)
        if m:
           pragmas.append(m.group(1))
           lastPragmaLine = i
        else:
           array.append(line.rstrip('\n\r'))
           i += 1
    array.insert(lastPragmaLine, '#pragma mark ' + ' '.join(pragmas))

with open("my.output.file", "w") as ins:
    for line in array:
        print(line, file=ins)

将内容复制到foo.py 并在您的机器上运行python foo.py(假设它有python 解释器,大多数情况下都有)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多