Вытаскивая ключевые слова с помощью стандартных утилит командной строки?

Запустите с основ, введя:

:.m15

Переместил бы ТЕКУЩУЮ строку ('. ') для выравнивания 15.

Кроме возможного создания пользовательской команды, которая приняла бы ведущее число, указывающее, ГДЕ Вы хотите, чтобы текущая строка была перемещена, ничто не приходит на ум, не приходит на ум ничто ПРОСТОЕ. (Rube Goldberg приходит на ум...),

command! -nargs=0 MyMove :.m<count>
nnoremap! mv :MyMove

МОГ БЫ работать, моя энергия-fu еще не сильна. Вы не предоставляли много информации, но это близко, я предполагаю.

2
07.08.2013, 00:46
3 ответа

С sed, Вы могли записать это как:

sed '/\([^:]*\):.*{IPA|\([^}]*\).*/!d;s//\1 \2/;s,/,,g;:1
     s/\(\([^ ]*\).*\)|/\1\n\2 /;t1'

Разбивка (@slm, спасибо)

Вышеупомянутая команда может быть сломана следующим образом:

  1. Вход синтаксического анализа в when: ... {IPA|...} и удалите несогласующие отрезки длинной линии.

    В /pattern/!d; s//repl/

    Мы [d] iscard строки, которые не соответствуют шаблону и затем снова используют тот же шаблон в следующей [s] команде замены (пустой шаблон означает снова использовать последний шаблон). Вместо [d] eleting несогласующие отрезки длинной линии, мы, возможно, оставили их нетронутыми при помощи b вместо d, или если мы знаем, что все строки соответствуют шаблону, мы могли использовать s/pattern/repl/ непосредственно.

    /\([^:]*\):.*{IPA|\([^}]*\).*/
    

    Тот шаблон разделяет данные на 2 блока. Первый блок when:. Этот бит кода, \([^:]*\): говорит для взятия всех символов, пока Вы не встречаетесь с a : и сохранить его во временном файле. переменная (\1).

    Все символы между : до и включая {IPA| пропускаются. Следующий бит это сохраняется, является всем после IPA|. Это сделано этим блоком кода, \([^}]*\), который говорит для сохранения всего кода до a } встречен. Это сохраняется в переменной (\2).

    Примечание: В sed любое время Вы хотите сохранить блок строки, можно перенести ее в круглые скобки. Их нужно оставить с a \ так, чтобы sed знает, что Вы не имеете в виду литерал paren. Как так: \( savethis \).

    пример

    $ sed 's/\([^:]*\):.*{IPA|\([^}]*\).*/\1 \2/;' sample.txt
    when /wɛn/|/ʍɛn/
    
  2. Удалите все наклонные черты вправо (/)

    Эти взгляды, более сложные, потому что это использует альтернативный разделитель. Вы обычно использовали бы форму s///g, но sed позвольте нам, Вы составляете разделители на лету, таким образом, мы используем запятые вместо этого (s,,,g). Это поиски блока для / и ничем заменяет их.

    пример

    $ sed '/\([^:]*\):.*{IPA|\([^}]*\).*/!d;s//\1 \2/;s,/,,g;' sample.txt
    when wɛn|ʍɛn
    
  3. Выполните итерации через каждый IPA

     :1 s/\(\([^ ]*\).*\)|/\1\n\2 /;t1
    

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

     :label command(s) t label
    

    Маркировка :1 команда (команды) s/\(\([^ ]*\).*\)|/\1\n\2 /; и t label "тест", который видит, изменила ли предыдущая команда пространство шаблона. Раз так затем перейдите для маркировки 1, следовательно t1.

  4. Команда в цикле

    Если мы берем label ... loop в течение секунды и увеличения наш пример IPA так, чтобы это имело 3, Вы видите то, что продолжается немного лучше.

    {{IPA|/wɛn/|/ʍɛn/|/blah/}}
    

    Мы закончим с этим, с помощью предыдущих команд для этой точки.

    when wɛn|ʍɛn|blah
    

    Если мы теперь выполняем это:

    $ echo "when wɛn|ʍɛn|blah" | sed 's/\(\([^ ]*\).*\)|/\1 \2 /;'
    

    Мы получаем это:

    when wɛn|ʍɛn
    when blah
    

    Можно ли видеть то, что это делает теперь? Да меня ни один, поэтому давайте упростим немного больше и возьмем новую строку (\n) и загрузите некоторые более короткие строки.

    более простой пример

    $ echo "X C1|C2|C3" | sed 's/\(\([^ ]*\).*\)|/\1 \2 /;'
    X C1|C2 X C3
    

    Теперь, что продолжается, вот то, что код \(\([^ ]*\).*\)| умно в том смысле, что это - вложение parens так, чтобы они были похожи на это ( ( ) ). То, что подбирается на внутренней части parens, является чем-либо, что это не пространство. Этот get's when строка. Внешние parens соответствуют всему до последнего канала (|).

    Другая интересная вещь с этим фрагментом кода состоит в том, что parens заказаны так, чтобы внешние были сохранены в \1 в то время как внутренние \2. Это вызвано тем, что sed нумерует их на основе порядка, в котором с ними встречаются.

    Можно убедить себя в этом путем расширения отрывка с помощью дополнительного \1и \2.

    $ echo "X C1|C2|C3" | sed 's/\(\([^ ]*\).*\)|/\1 \1 \1 /;'
    X C1|C2 X C1|C2 X C1|C2 C3
    
    $ echo "X C1|C2|C3" | sed 's/\(\([^ ]*\).*\)|/\1 \2 \2 /;'
    X C1|C2 X X C
    

    Таким образом, команда в цикле в основном берет X 2 раза. Однажды как часть целого X C1|C2 (снаружи parens) и во второй раз как что-либо до пространства (внутри parens).

  5. Назад к условному переходу

    Хорошо, таким образом, ответвление в основном собирается назвать команду в № 5 для IPA's, где существуют больше чем 2. sedконструкция ответвления будет продолжать повторно выполнять команду, пока команда больше не изменит замену, в которой точке она останавливается.

    пример

    $ echo "X C1|C2|C3" | sed ':1 s/\(\([^ ]*\).*\)|/\1\n\2 /; t1'
    X C1
    X C2
    X C3
    

Надо надеяться, вышеупомянутое поможет другому прохожему к этому ответу в будущем.

5
27.01.2020, 21:51
  • 1
    Не знайте, как Вы поняли это и не можете понять его, но это работает! –  Yimin Rong 06.08.2013, 23:54
  • 2
    @YiminRong - да у Stephane есть некоторые лучшие ответы на сайте. Он и Gilles. –  slm♦ 07.08.2013, 00:03
  • 3
    @YiminRong - если Вы начинаете повреждать его вниз, Вы видите, как это работает. –  slm♦ 07.08.2013, 00:06
  • 4
    Вы заботитесь, подробно останавливается ли кто-то на Ваших ответах, чтобы объяснить, как они работают? –  slm♦ 07.08.2013, 00:06
  • 5
    Почему это также работает? sed '/\([^:]*\):.*{IPA|\([^}]*\).*/!d;s//\1 \2/;s,/,,g;s/\(\([^ ]*\).*\)|/\1\n\2 /; Что делает роль :1 и t1 игра? А-ч большое спасибо –  slm♦ 07.08.2013, 00:12

С жемчугом в сценарии жемчуга (обработка STDIN)

while(<>) {
    if(/^([^:]+):.*{{IPA\|([^}]+)}}/) { 
        print "$1 $_\n" foreach(split /\|/, $2); 
    }
}

или на командной строке (передача по каналу)

perl -ne ' if(/^([^:]+):.*{{IPA\|([^}]+)}}/) { print "$1 $_\n" foreach(split /\|/, $2); }'
2
27.01.2020, 21:51

С ударом и grep

line='when:* {{a|US}} {{enPR|wĕn|hwĕn}}, {{IPA|/wɛn/|/ʍɛn/}}, {{X-SAMPA|/wEn/|/WEn/}}'
IFS=$': \t' read -ra words <<< "$line"
for item in "${words[@]}"; do
    if [[ $item == "{{IPA|"* ]]; then
        grep -o '/[^/]\+/' <<< "$item" | while read -r pronunc; do
             echo "${words[0]} ${pronunc//\//}"
        done
    fi
done
1
27.01.2020, 21:51

Теги

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