Вид ввел файл результатами regex

Поэтому жемчуг читает текстовый файл одна строка за один раз и применяет шаблон замены к каждой строке - поэтому, если будет несколько случаев маркера в различных строках, то они будут все заменены.

Для замены просто первого вхождения в файле можно добавить -0 опция, которая устанавливает входной разделитель записей на нулевой символ и заставляет жемчуг считать целый файл прежде, чем сделать замену.

7
13.08.2012, 22:17
5 ответов

Общий метод отсортировать по произвольной функции содержания строки следующие:

  1. Получите ключ, который Вы хотите отсортировать по и скопировать его в начало строки
  2. Вид
  3. Удалите ключ с начала строки

Вот ключ, который можно использовать в данном случае: это sed программа произведет строку от последнего идентификатора в конец.

% sed -e 's/^.*[^[:alnum:]_]\([[:alpha:]][[:alnum:]_]*\)/\1/' < decls

albumArtView; // 1
profileView;  // 2
postFB;          // 3
saveButton;      // 4

Помещать эти ключи и исходные строки рядом:

% paste <(sed -e 's/^.*[^[:alnum:]_]\([[:alpha:]][[:alnum:]_]*\)/\1/' < decls) decls

Отсортировать их...

| sort

и покинуть просто второе поле (исходная строка)

| cut -f 2-

Все вместе (сортирующий в обратном порядке, таким образом, существует что-то для показа):

% paste <(sed -e 's/^.*[^[:alnum:]_]\([[:alpha:]][[:alnum:]_]*\)/\1/' < decls) decls \
  | sort -r \
  | cut -f 2-

@property (nonatomic, assign) UIButton *saveButton;      // 4
@property (nonatomic, strong, readonly) UIImageView *profileView;  // 2
@property (nonatomic, strong, readwrite) UIButton *postFB;          // 3
@property (nonatomic, strong) id <AlbumArtDelegate, UITextFieldDelegate> *albumArtView; // 1
11
27.01.2020, 20:16
  • 1
    Просто примечание b/c OP, вероятно, захочет адаптировать этот подход. При помощи \1 & в выражении замены команды замены sed можно пропустить decls временный файл и paste вызов. Кроме того, regex должен был бы быть настроен для соответствия только идентификатору (данный пример дал бы осечку, если бы комментарий в конце строки содержал какие-либо идентификаторы без чисел). –  jw013 13.08.2012, 22:36
  • 2
    Спасибо, @angus!. Принимая во внимание комментарий @jw013, я уверен, что это будет работать красиво на то, что я хочу. –  kubi 13.08.2012, 22:38
  • 3
    @jw013: Да, я думал, что он мог бы хотеть использовать другой инструмент для получения ключа - возможно, он знает жемчуг или awk. В этом случае, использование paste дженерик, "наименьшее количество знаменателя" решение. Btw, который должен быть вкладкой между \1 и & (невозможный различать отсюда). –  angus 13.08.2012, 22:43
  • 4
    @kubi, довольный помогать. :) –  angus 13.08.2012, 22:47
  • 5
    , я закончил тем, что не делал этой точной вещи, но вместо этого поместил рубиновый сценарий в Сервис Automator.app. jimkubicek.com/blog/2012/09/20/sort-methods-with-automator –  kubi 21.09.2012, 07:29
PIPED-DATA | sed -r "s/(\*\w+)/\x01&\x01/" | sort -k2 -t$'\x01' |tr -d $'\x01'

Вышеупомянутый сценарий достаточно для Вашей ситуации. На самом деле это в основном достаточно для любого вида единственного поля ключа.. Для того же сценария, расширенного, продолжает читать.


Следующий сценарий создает поле, которое будет отсортировано как 2, но полевой макет является довольно перетекающим. Можно отсортировать на нескольких полях, если Вы должны путем определения соответствующих regex шаблонов и изменения опций вида соответственно.

Каждый полевой шаблон должен быть перенесен в нормальный (скобки) и 'single-quoted'.

Шаблоны, которые Вы обеспечиваете, разграничены любым уникальным символом, который Вы выбираете. sed также нуждается в уникальном разделителе. Сценарий использует разделители \x01 и \x02. Эти значения разделителя были выбраны, потому что они обычно не появляются в текстовых файлах.

Обратите внимание, что Вашу установку должны рассмотреть как бывшее основанное поле composiiton, не разделители полей..

n=2                                  # field number to sort on
p=( '(.*)'  '(\*\w+)'  '(.*)' )      # Set up regex field patterns

f=; r=; d=$'\x01';  x=$'\x02'        # Build patterns and delimiters
for (( i=0; i<${#p[@]}; i++ )) ;do 
   f+="${p[i]}"; r+="\\$((i+1))$x"
done

sed -r "s$d$f$d$r$d" file |sort -k$n -t"$x" |tr -d  "$x"

Вывод:

@property (nonatomic, strong) id <AlbumArtDelegate, UITextFieldDelegate> *albumArtView; // 1
@property (nonatomic, strong, readwrite) UIButton *postFB;          // 3
@property (nonatomic, strong, readonly) UIImageView *profileView;  // 2
@property (nonatomic, assign) UIButton *saveButton;      // 4
2
27.01.2020, 20:16
sort -k 5 ~/Temp/data

работавший для меня на Cygwin.

1
27.01.2020, 20:16
  • 1
    Обновленный мой вопрос с более трудным (и реалистичный) пример –  kubi 13.08.2012, 22:17

Это использует Python. Синтаксис Python не хорош для острот кроме оболочки удара, счастливо обработает две строки, и код может использовать двойные кавычки для своих строковых констант :-)

Программы сортировки Python позволяют Вам использовать функцию лямбды для извлечения ключа для строк, которые будут отсортированы на (украшение, вид, un-dercorate других методов).

regexp, который я использую просто, извлекает слово непространства после первого '*' подстрока в строках.

paddy$ python -c 'import sys, re
print ("\n".join(sorted((line.rstrip() for line in sys.stdin), key=lambda x: re.search(r"\s[*](\S+)", x).group(1))))' < test_in2.txt 
(nonatomic, strong) id <AlbumArtDelegate, UITextFieldDelegate> *albumArtView; // 1
@property (nonatomic, strong, readwrite) UIButton *postFB;          // 3
@property (nonatomic, strong, readonly) UIImageView *profileView;  // 2
@property (nonatomic, assign) UIButton *saveButton;      // 4
paddy$ 
0
27.01.2020, 20:16
  • 1
    Если Вам нравится использовать Python этот путь, я рекомендую pythonpy. С ним Ваш код может быть написан как py -l 'sorted(l, key=lambda x: re.search(r"\s[*](\S+)", x).group(1)) '< test_in2.txt, если я не сделал испорченной круглой скобки. –  GingerPlusPlus 05.02.2016, 19:13
  • 2
    Спасибо Имбирь, но нет, спасибо. Я довольно рад использовать awk/Perl/sed для расширенных острот, если я должен, но предпочитать использовать настоящий Python. –  Paddy3118 15.02.2016, 00:52

Я создал Perl-скрипт именно для этого, вы можете ввести регулярное выражение для сортировки файла по первому захвату. затем вы можете установить флаг для строкового или числового сравнения. просто поместите этот образец кода в файл .pl.

это довольно просто, и логика действительно находится в строках 20-37.

#! /usr/bin/perl
# Created by pete Nixon

use Getopt::Long;
use strict;
use Cwd qw(abs_path);

my $exec_path = abs_path($0);
   $exec_path =~ s/(.*\x2f)[^\x2f]+$/$1/g;
my $path = abs_path($1);

&getCommandLineArguments;

my $file_flag;
my $regex;
my $type_flag;
my @lines;
my @sortedLines;

open (FILE, $file_flag) || die "Couldn't open rule file, $!";
while (<FILE>) {
    chomp $_;
    if ($_ =~ /^\s*\n/) {
        next;
    }
    push (@lines, $_);
}

if ($type_flag eq 1) {
    @sortedLines = sort { ($a =~ m/$regex/)[0] <=> ($b =~ m/$regex/)[0]} @lines; # where the magic happens
} else {
    @sortedLines = sort { ($a =~ m/$regex/)[0] cmp ($b =~ m/$regex/)[0]} @lines; # where the magic happens
}

foreach (@sortedLines) {
    print "$_\n";
}

sub getCommandLineArguments() {
    my $help;
    my $clear = "[0m";
    my $black = "[0;30m";
    my $blue = "[0;34m";
    my $green = "[0;32m";
    my $cyan = "[0;36m";
    my $red = "[0;31m";
    my $purple = "[0;35m";
    my $brown = "[0;33m";
    my $gray = "[0;37m";
    my $darkGray = "[1;30m";
    my $lightBlue = "[1;34m";
    my $lightGreen = "[1;32m";
    my $lightCyan = "[1;36m";
    my $lightRed = "[1;31m";
    my $lightPurple = "[1;35m";
    my $yellow = "[1;33m";
    my $white = "[1;37m";
    GetOptions (
        'file|f=s' =>   \$file_flag,
        'regex|r=s' => \$regex,
        'type|t=s' => \$type_flag,
        'help|h|?' => \$help
        ) or die ("Error in command line arguments$clear\n");
    if ($help || $file_flag eq undef && $regex eq undef) {
        print "$green================================================================================$clear\n";
        print "$red WHAT DOES THIS SCRIPT DO?\n$clear";
        print "$cyan    - This program a regex and sorts a line based on it.\n$clear";
        print "$red HOW DO I USE THIS SCRIPT?\n$clear";
        print "$cyan    - Type the name of this script, space, options (see the next section)\n$clear";
        print "$green   SAMPLE: '$clear" . "sortbyregex.pl -f file -r \"regex\" -t (1|2)$green'\n$clear";
        print "$red WHAT OPTIONS ARE AVAILABLE?\n$clear";
        print "$yellow  -f, --file\n$clear";
        print "$cyan    - Use to specify a regex\n$clear";
        print "$yellow  -r, --regex\n$clear";
        print "$cyan    - Use to specify the regex used for sorting, must include one capture\n$clear";
        print "$yellow  -t, --type\n$clear";
        print "$cyan    - Use to specify the type of sorting 1 = numeric 2 = string\n$clear";
        print "$yellow  -h, --help, -?\n$clear";
        print "$cyan    - Use to see this help... so... yeah...\n$clear";
        print "$green================================================================================$clear\n";
        exit(0);
    }
}
0
27.01.2020, 20:16

Теги

Похожие вопросы