为什么我的find命令不起作用?

时间:2015-02-26 14:55:26

标签: bash replace awk terminal

对于我们的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 -字符。但是,上面的命令不会终止。它根本不会改变任何东西。

3 个答案:

答案 0 :(得分:3)

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

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

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

但有一个问题:同样,shell将首先进行重定向。这意味着它会为$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%确保在您不希望它发生的地方不替换该字符串。

答案 1 :(得分:1)

如果您的awk版本是> = 4.1.0,则可以执行

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

答案 2 :(得分:0)

这应该有效:

#!/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解释器,大多数都这样做。)