Как читать в исходном тексте в unix? [Дубликат]

Это очень распространенная проблема, возникающая из-за непонимания работы :nth-child() и :nth-of-type(). К сожалению, в настоящее время нет решения на основе селектора, поскольку селектор не обеспечивает способ сопоставления n-го дочернего элемента, который соответствует произвольному селектору на основе шаблона, такого как нечетные, четные или любые an+b, где a != 1 и b != 0.

:nth-child() псевдокласса подсчитывает элементы среди всех всех их братьев и сестер под одним и тем же родителем. Он не учитывает только братьев и сестер, которые соответствуют остальной части селектора. Аналогично, псевдо-класс :nth-of-type() считает, что siblings используют один и тот же тип элемента, который относится к имени тега в HTML, а не к остальной части селектора.

Это также означает, что если все дочерние элементы одного и того же родителя имеют один и тот же тип элемента, например, в случае тела таблицы, единственными дочерними элементами которого являются tr или элемент списка, единственными дочерними элементами которого являются li, тогда :nth-child() и :nth-of-type() будут вести себя одинаково, т. е. для каждого значения an+b, :nth-child(an+b) и :nth-of-type(an+b) будут соответствовать одному и тому же набору элементов.

На самом деле все простые селектора в данном соединении селектор, включая псевдоклассы, такие как :nth-child() и :not(), работают независимо друг от друга , вместо того, чтобы смотреть на подмножество элементов, которые сопоставляются остальными селектора.

Это также подразумевает, что нет понятия порядка среди простых селекторов в каждом отдельном селекторе 1, что означает, например, следующие два селектора эквивалентны:

[f 1]

При переводе на английский язык оба означают:

Выберите любой элемент tr, который соответствует всем следующим независимым условиям:

  • нечетный номер родительского родителя;
  • имеет класс «строка»; и
  • является потомком элемента table, который имеет класс «myClass».
blockquote>

(вы заметите, что мое использование неупорядоченный список здесь, просто для того, чтобы управлять точкой.)

Поскольку в настоящее время нет чистого решения CSS, вам придется использовать скрипт для фильтрации элементов и соответственно применять стили или дополнительные имена классов. Например, следующее обходное решение, использующее jQuery (предполагается, что в таблице есть только одна группа строк, заполненная элементами tr):

$('table.myClass').each(function() {
  // Note that, confusingly, jQuery's filter pseudos are 0-indexed
  // while CSS :nth-child() is 1-indexed
  $('tr.row:even').addClass('odd');
});

С соответствующим CSS:

table.myClass tr.row.odd {
  ...
}

Если вы используете автоматические инструменты тестирования, такие как Selenium или обрабатываете HTML с помощью таких инструментов, как lxml, многие из этих инструментов позволяют XPath в качестве альтернативы:

//table[contains(concat(' ', @class, ' '), ' myClass ')]//tr[contains(concat(' ', @class, ' '), ' row ')][position() mod 2)=1]

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


Для чего это стоит, есть предложение для расширения к :nth-child() нотации , которое должно быть добавлено к Селекторы уровня 4 для конкретной цели выбора каждого n-го дочернего элемента, соответствующего данному селектору.2

Селектор, в котором для фильтрации совпадений предоставляется в качестве аргумента :nth-child(), снова из-за того, как селектора работают независимо от друг друга в последовательности, продиктованной существующим синтаксисом селектора. Итак, в вашем случае это будет выглядеть так:

table.myClass tr:nth-child(odd of .row)

(Проницательный читатель сразу заметит, что это должно быть :nth-child(odd of tr.row) вместо этого, поскольку простые селектор tr и :nth-child() работают независимо друг от друга. Это одна из проблем с функциональными псевдоклассами, которые принимают селекторы, банку червей, которую я предпочитаю не открывать посреди этого ответа. Вместо этого я собираюсь перейти к предположению что большинство сайтов не будут иметь каких-либо других элементов, кроме элементов tr, как братьев и сестер друг друга в теле таблицы, что сделает любой вариант функционально эквивалентным.)

Конечно, будучи новым предложением в новая спецификация, это, вероятно, не увидит реализацию до нескольких лет в будущем. В то же время вам придется придерживаться сценария, как указано выше.


1 Если вы укажете тип или универсальный селектор, он должен быть первым. Однако это не меняет того, как работают селекторы. это не что иное, как синтаксический приступ.

2 Первоначально это было предложено как :nth-match(), однако, поскольку оно по-прежнему считает элемент относительным только для его братьев и сестер, а не для каждого другого элемента, который соответствует данному селектору, он с тех пор, как с 2014 года был перепрофилирован как расширение существующего :nth-child().

49
задан hotpaw2 12 July 2012 в 17:30
поделиться

5 ответов

Нет. Расширение происходит до того, как команда будет запущена. Вы можете только отключить glob перед запуском команды или путем цитирования звезды.

$ # quote it
$ foo '*'

$ # or escape it
$ foo \*

$ # or disable the glob (noglob)
$ set -f
$ foo *
78
ответ дан codeforester 19 August 2018 в 02:30
поделиться
  • 1
    также, если нечего расширять, нет расширения. т. е. с пустым pwd, echo * является просто * – sam boosalis 1 April 2014 в 00:48
  • 2
    @sam Это зависит от того, как ваши параметры установлены. Из tldp: "Если имена подходящих файлов не найдены, а опция оболочки nullglob отключена, слово остается неизменным. Если параметр nullglob установлен, и совпадений не найдено, слово удаляется. & Quot; – Chris Middleton 6 February 2015 в 19:05
  • 3
    спасибо, я должен был квалифицировать, что это было только от наблюдения, а не от какого-либо понимания. – sam boosalis 6 February 2015 в 22:31

Остерегайтесь: если нет имен, соответствующих маске, bash передает аргумент as-is без расширения!

Proof (pa.py - очень простой скрипт, который просто печатает свои аргументы):

 $ ls
f1.cc  f2.cc  pa.py
 $ ./pa.py *.cc
['./pa.py', 'f1.cc', 'f2.cc']
 $ ./pa.py *.cpp
['./pa.py', '*.cpp']
1
ответ дан A-B-B 19 August 2018 в 02:30
поделиться
  • 1
    Не всегда. set -o nullglob или shopt -s failglob, и это поведение изменится (двумя разными способами). – Charles Duffy 1 December 2015 в 01:22

Расширение выполняется оболочкой перед запуском вашей программы. Ваша программа не имеет понятия, произошло ли расширение или нет.

   set -o noglob

отключит расширение в вызывающей оболочке, но вам нужно будет сделать это перед , вы вызываете свою программу.

Альтернатива процитировать ваши аргументы, например

foo "*"
6
ответ дан Brian Agnew 19 August 2018 в 02:30
поделиться
  • 1
    setopt представляется как zsh-специфическая команда. Как сказал другой плакат, для bash вы используете set -o noglob для отключения расширения подстановочных знаков. – Wirawan Purwanto 4 March 2016 в 22:31
  • 2
    Теперь исправлены. спасибо – Brian Agnew 1 June 2018 в 11:45

Хотя верно, что сама команда не может отключить глобус, пользователь может сказать оболочке Unix, чтобы не глотать определенную команду. Обычно это делается путем редактирования файлов конфигурации оболочки. Предполагая, что команда foo может быть найдена по пути к команде, в соответствующий файл конфигурации необходимо добавить следующее:

Для оболочек sh, bash и ksh:

alias foo='set -f;foo';foo(){ command foo "$@";set +f;}

Для оболочек csh и tcsh:

alias foo 'set noglob;\foo \!*;unset noglob'

Для оболочки zsh:

alias foo='noglob foo'

Путь к командной строке не нужно использовать. Скажем, команда foo хранится в каталоге ~ / bin, а затем следующее:

Для оболочек sh, bash и ksh:

alias foo='set -f;foo';foo(){ ~/bin/foo "$@";set +f;}

Для csh и tcsh shells:

alias foo 'set noglob;$home/bin/foo \!*;unset noglob'

Для оболочки zsh:

alias foo='noglob ~/bin/foo'

Все вышеперечисленное было протестировано с использованием OSX 10.9.2 от Apple. Примечание. При копировании вышеуказанного кода будьте осторожны при удалении любых пробелов. Они могут быть значительными.

Обновление:

Пользователь geira указал, что в случае оболочки bash

alias foo='set -f;foo';foo(){ ~/bin/foo "$@";set +f;}

можно заменить на

reset_expansion(){ CMD="$1";shift;$CMD "$@";set +f;}
alias foo='set -f;reset_expansion ~/bin/foo'

, что устраняет необходимость в функции foo.

Некоторые веб-сайты, используемые для создания этого документа:

39
ответ дан Community 19 August 2018 в 02:30
поделиться
  • 1
    Это должен был быть принятый ответ, поскольку он доказывает, что действительно возможно сделать то, что хочет OP. Для некоторых более совершенных методов в bash эта ссылка документирует различные варианты: blog.edwards-research.com/2011/05/preventing-globbing – geira 23 April 2015 в 08:40
  • 2
    @geira: Иногда ответ принимается до того, как будет опубликован лучший ответ. Я считаю, что это может быть один из таких случаев. Я также считаю, что ответ отмечает, как большинство полезных пользователей заканчивается первым. Примечание. Я добавил свой вклад в свой ответ. – David Anderson 27 April 2015 в 14:11
  • 3
    @geira, OP хочет, чтобы скомпилированная программа связывалась с оболочкой; ответ на то, что можно настроить оболочку, чтобы вести себя по желанию по командной строке, является полезным ответом, и я сам соглашусь с этим, но я вижу, что можно не согласиться с тем, полностью ли он включен. – Charles Duffy 1 December 2015 в 01:24
  • 4
    Тот факт, что он может быть выполнен, не означает, что он должен быть выполнен. При изменении поведения оболочки от разумного ожидания пользователя для выбранных команд звучит удивительно и в конечном итоге нежелательно. – tripleee 29 July 2016 в 05:36
  • 5
    @ tripiple: Было время, когда люди ожидали реле и вакуумные трубки. Ожидались отверстия, пробитые картонными карточками и бумажной лентой. Люди придерживались правил слайдов, а не калькуляторов и телефонов. Полагаю, для вас это было бы желательно. В те времена мне было все равно. Мне нравится видеть, что будет дальше. – David Anderson 29 July 2016 в 11:31

Нет. Оболочка типа Bourne всегда выполняет globbing , когда это необходимо, перед выполнением команды. Пользователь должен указывать или избегать аргументов, чтобы предотвратить глобус, например foo \*; фактическая выполняемая программа не может указывать предпочтения.

0
ответ дан mrb 19 August 2018 в 02:30
поделиться
  • 1
    Также у этой оболочки есть стиль Bourne. Это не setopt, но set -o noglob. – Anne van Rossum 4 December 2013 в 14:57
Другие вопросы по тегам:

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