2015-02-26 3 views
1

Для нашего проекта IOS Я хочу, чтобы объединить старые стиль Pragma линии какПочему моя команда find не работает?

#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 -. Однако команда выше не заканчивается. Это ничего не меняет.

+1

Вы не можете 'awk file> file' (то, что вы используете, не имеет значения), терминал обрезает выходной файл * немедленно *, поэтому ваша команда никогда не видит содержимого файла. –

+0

@EtanReisner Спасибо за этот намек. Поскольку я полный новичок в магической магии, я не знаю, как обойти эту проблему. – Bastian

+2

Вы работаете с одним файлом и выходите на другой, а затем переместите новый файл поверх старого файла. –

ответ

3

Когда вы нажимаете enter, оболочка сначала обрабатывает любые перенаправления, в данном случае > {}. Это происходит до того, как оболочка создаст процесс для find, так как ему необходимо подключить выход процесса find к {}. Это означает, что вы должны найти файл {} в текущей папке.

Я думаю, что вы лучше с петлей в этом случае:

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

но есть загвоздка: Опять же, оболочка будет сначала сделать перенаправление. Это означает, что он создаст пустой$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% уверенным, что строка не будет заменена в местах, где вы не хотите, чтобы это произошло.

+0

Хотя я полагаю, что опубликованный код работает безупречно, ваш последний намек на способности IDE имеет решающее значение. С помощью этой информации я искал многострочный поиск/замену в XCode и нашел эту большую запись SO: http://stackoverflow.com/questions/5522258/how-to-replace-multi-new-line-with-single-new -line-in-xcode-using-find-replace – Bastian

+0

Связанный: http://stackoverflow.com/questions/7039130/bash-iterate-over-list-of-files-with-spaces –

1

Если AWK версия> = 4.1.0, вы можете сделать

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

Полезный вариант, но 'awk 'команда, которую вы скопировали из вопроса, неверна, и ни' find', ни, по крайней мере, избегают фигурных скобок. – Birei

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, что большинство делает).