использовать пробел в качестве разделителя с командой cut - PullRequest
282 голосов
/ 03 мая 2009

Я хочу использовать пробел в качестве разделителя с командой cut.

Какой синтаксис я могу использовать для этого?

Ответы [ 8 ]

318 голосов
/ 03 мая 2009
cut -d ' ' -f 2

Где 2 - это номер поля поля, разделенного пробелами, который вы хотите.

142 голосов
/ 28 сентября 2013

Обычно, если вы используете пробел в качестве разделителя, вы хотите рассматривать несколько пробелов как один, поскольку вы анализируете выходные данные команды, выравнивающей некоторые столбцы с пробелами. (и поиск в Google это приводит меня сюда)

В этом случае одной команды cut недостаточно, и вам необходимо использовать:

tr -s ' ' | cut -d ' ' -f 2

или

awk '{print $2}'
37 голосов
/ 02 мая 2015

В дополнение к существующим, полезные ответы; Подсказка к Поддержка QZ за то, что меня попросили опубликовать отдельный ответ:

В игру вступают два различных механизма :

  • (a) требует ли сам cut разделитель (в данном случае пробел), передаваемый опции -d, в качестве отдельного аргумента или допустимо добавить напрямую к -d.

  • (b) как shell обычно анализирует аргументы перед передачей их вызываемой команде.

(a) отвечает цитатой из Руководства POSIX для утилит (выделено мной)

Если в синопсисе стандартной утилиты показана опция с обязательным аргументом-параметром [...], соответствующее приложение должно использовать отдельных аргументов для этой опции и его опция-аргумент . Однако , соответствующая реализация должна также разрешать приложениям указывать параметр и параметр-аргумент в одной и той же строке аргумента без промежуточных символов .

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

  • (s) ИЛИ: отдельный аргумент
  • (d) ИЛИ: в качестве значения , непосредственно присоединенного к -d.

После того, как вы выбрали (ы) или (d), имеет значение shell для строкового литерала - (b) - что имеет значение:

  • При подходе (s) все следующие формы эквивалентны:

    • -d ' '
    • -d " "
    • -d \<space> # <space> used to represent an actual space for technical reasons
  • При подходе (d) , все следующие формы эквивалентны:

    • -d' '
    • -d" "
    • "-d "
    • '-d '
    • d\<space>

Эквивалентность объясняется строковой литеральной обработкой shell :

Все решения , приведенные выше, приводят к точно такой же строке (в каждой группе) к моменту, когда cut видит их :

  • (s) : cut видит -d в качестве своего собственного аргумента, за которым следует отдельный аргумент, содержащий пробел char - без кавычек или \ префикс!.

  • (d) : cut видит -d плюс пробел - без кавычек или \ префикс! - как часть того же аргумента .

Причина, по которой формы в соответствующих группах в конечном итоге идентичны, двояка: как shell анализирует строковые литералы :

  • Оболочка позволяет указывать литерал от как есть до механизм, называемый цитированием , который может принимать несколько форм :
    • одиночные кавычки строки: содержимое '...' взято буквально и образует одиночный аргумент
    • двойные кавычки строки: содержимое внутри "..." также формирует одиночный аргумент, но подвергается интерполяции (расширяет ссылки на переменные, такие как $var, подстановки команд ($(...) или `...`) или арифметические разложения ($(( ... ))).
    • \ -цитирование отдельных символов : \, предшествующий одному символу, приводит к тому, что этот символ интерпретируется как литерал.
  • Цитирование дополняется удалением кавычек , что означает, что после того, как оболочка проанализировала командную строку, она удаляет символов кавычек из аргументы (включая '...' или "..." или \ экземпляров) - таким образом, вызываемая команда никогда не видит кавычки .
34 голосов
/ 04 мая 2009

Вы также можете сказать

cut -d\  -f 2

обратите внимание, что после обратной косой черты есть два пробела.

4 голосов
/ 22 апреля 2015

I только что обнаружил , что вы также можете использовать "-d ":

cut "-d "

Тест

$ cat a
hello how are you
I am fine
$ cut "-d " -f2 a
how
am
3 голосов
/ 14 мая 2015

Вы не можете сделать это легко с помощью cut, если данные имеют, например, несколько пробелов Я нашел полезным нормализовать ввод для более легкой обработки. Один из способов - использовать sed для нормализации, как показано ниже.

echo -e "foor\t \t bar" | sed 's:\s\+:\t:g' | cut -f2  #bar
3 голосов
/ 01 августа 2013

scut , утилита, похожая на сокращение (умнее, но медленнее, которую я сделал), которая может использовать любое регулярное выражение perl в качестве ломающего токена Разбивка на пробелах используется по умолчанию, но вы также можете разбивать регулярные выражения с несколькими символами, альтернативные регулярные выражения и т. Д.

scut -f='6 2 8 7' < input.file  > output.file

, поэтому приведенная выше команда будет разбивать столбцы на пробелах и извлекать столбцы (на основе 0) 6 2 8 7 в ​​указанном порядке.

0 голосов
/ 29 мая 2018

У меня есть ответ (я допускаю несколько запутанный ответ), который включает sed, регулярные выражения и группы захвата:

  • \S* - первое слово
  • \s* - разделитель
  • (\S*) - второе слово - захвачено
  • .* - остаток линии

В качестве выражения sed необходимо захватить группу захвата, т. Е. \( и \).

\1 возвращает копию захваченной группы, то есть второе слово.

$ echo "alpha beta gamma delta" | sed 's/\S*\s*\(\S*\).*/\1/'
beta

Когда вы смотрите на этот ответ, он несколько запутывает, и, вы можете подумать, зачем беспокоиться? Ну, я надеюсь, что некоторые из них могут пойти "Ага!" и будет использовать этот шаблон для решения некоторых сложных проблем извлечения текста с помощью одного sed выражения.

...