Неправда, справочная страница для cut не объясняет этого и, как правило, не информативна
UncleZeiv 5.10.10
2
Кроме того, «сокращение информации» не является улучшением в этом случае.
Кардифф космический человек
3
@ mklement0, если я вспоминаю, я отвечал на комментарий, который с тех пор был удален, на который был отклонен этот вопрос как ответ на странице руководства, что, на мой взгляд, было "неверным", несмотря на то, что для этого были веские причины или нет - сейчас, хотя я допускаю, что для такого недостатка информации может быть веская причина, я все же думаю, что документация без примеров общего использования часто, по крайней мере, раздражает, а
иногда и
3
@UncleZeiv Понял; Спасибо за разъяснение; учитывая интерес к этому вопросу, можно предположить, что этой manстраницы недостаточно. Давайте посмотрим: « -d delimИспользуйте delimв качестве символа разделителя полей вместо символа табуляции». (BSD cut, но версия GNU и спецификация POSIX в значительной степени утверждают одно и то же). Использование оболочки для вызова cut- типичный случай - поэтому требует, чтобы вы знали, как обычно передавать пробел в качестве аргумента, используя синтаксис оболочки , что, возможно, не cutявляется работой man-страницы. Однако примеры из реальной жизни всегда помогают, а в справочной странице GNU их нет.
mklement0
4
хотя выбранный ответ является технически правильным, рассмотрите возможность выбора более свежего и всеобъемлющего ответа @ mklement0 в качестве канонического ответа, чтобы он отфильтровывался вверх.
Дэвид Лебауэр
Ответы:
367
cut -d ' '-f 2
Где 2 - номер поля, которое вы хотите разделить пробелом.
Можете ли вы указать cut использовать любое число определенного символа в качестве разделителя, как в RegEx? например, любое количество пробелов, например, \ s +
амфибия
3
@ foampile Нет, я не верю, что ты можешь.
Джонатан Хартли
6
Вы не можете использовать регулярные выражения с cut, но вы можете с помощью cutsкоторых пытается «исправить» все cutограничения: github.com/arielf/cuts
arielf
Вы можете получить каждое третье поле, разделенное пробелом? как cut -d ' ' -f 3,6,9,12,15,18без указания каждого номера?
Monocito
169
Обычно, если вы используете пробел в качестве разделителя, вы хотите рассматривать несколько пробелов как один, потому что вы анализируете выходные данные команды, выравнивающей некоторые столбцы с пробелами. (и поиск в Google это приводит меня сюда)
В этом случае одной cutкоманды недостаточно, и вам нужно использовать:
Спасибо за пример использования awk, именно то, что мне было нужно.
Спазм
44
Дополнять существующие полезные ответы; подсказка к QZ Поддержка за то, что я рекомендую опубликовать отдельный ответ:
Здесь действуют два разных механизма :
(а) является ли cutсам по себе требует разделителя (пространства, в данном случае) передается -dвозможности быть отдельным аргументом или является ли это приемлемо , чтобы добавить его непосредственно к -d.
(б) как оболочка обычно анализирует аргументы перед передачей их вызываемой команде.
Если в ОПИСАНИИ стандартной утилиты показан параметр с обязательным аргументом option [...], то соответствующее приложение должно использовать отдельные аргументы для этого параметра и его аргумента option . Однако соответствующая реализация также должна позволять приложениям указывать параметр и параметр-аргумент в одной строке аргумента без промежуточных символов .
Другими словами: в этом случае, поскольку -dпараметр-аргумент является обязательным , вы можете выбрать , указывать ли разделитель следующим образом :
(s) ИЛИ: отдельный аргумент
(d) ИЛИ: как значение, непосредственно связанное с-d .
После того, как вы выбрали (s) или (d), именно строковый литеральный синтаксический анализ оболочки - (b) - имеет значение:
При подходе (ях) все следующие формы эквивалентны:
-d ' '
-d " "
-d \<space> # <space> used to represent an actual space for technical reasons
При подходе (d) все следующие формы эквивалентны:
-d' '
-d" "
"-d "
'-d '
d\<space>
Эквивалентность объясняется оболочкой строковой литеральной обработкой :
Все приведенные выше решения приводят к появлению точно такой же строки (в каждой группе) к тому времени, когда cutони их увидят :
(s) : cutвидит в -dкачестве своего собственного аргумента отдельный аргумент, содержащий пробел - без кавычек или \префиксов !.
(d) : cutвидит -dплюс пробел - без кавычек или \префиксов! - как часть того же аргумента.
Причина, по которой формы в соответствующих группах в конечном итоге идентичны, двояка, в зависимости от того, как оболочка анализирует строковые литералы :
Оболочка позволяет указывать литерал как есть через механизм, называемый цитированием , который может принимать несколько форм :
строки в одинарных кавычках : содержимое внутри '...'воспринимается буквально и образует единый аргумент
строки в двойных кавычках : содержимое внутри "..."также формирует один аргумент, но подвергается интерполяции (расширяет ссылки на переменные, такие как $varподстановки команд ( $(...)или `...`) или арифметические расширения ( $(( ... ))).
\-цитирование отдельных символов : \предшествующий одному символу этот символ интерпретируется как литерал.
Цитирование дополняется удалением кавычек , что означает, что после того, как оболочка проанализировала командную строку, она удаляет символы кавычек из аргументов (включающие '...'или "..."или \экземпляры) - таким образом, вызываемая команда никогда не видит символы кавычек .
Человек, который знает, что «\» убегает от следующего символа, будет очень осторожен, чтобы заметить, что будет дальше. Использование '\' для экранирования таких символов - очень распространенная идиома.
Джонатан Хартли
3
@ Джонатан Хартли, как правило, большинство кодов на самом деле нечитаемы :)
Лука Боррионе
1
С точки зрения Linux / Unix, это \ была моя первая попытка, и она сработала. Я согласен, что это менее очевидно по сравнению с ' ', но я уверен, что многие рады прочитать это здесь как подтверждение поведения. Для лучшего понимания смотрите комментарий @ mklement0 ниже.
Tresf
@JonathanHartley исправление: « эгоист, который знает, что« \ »убегает от следующего персонажа и предполагает, что все остальные тоже это знают». Для личных проектов это не относится, но в условиях команды это предположение является очень опасным (и потенциально дорогостоящим).
Эдуард Никодей
1
@EduardNicodei О, я согласен. Мы говорили о читателях кода («кто замечает ...?»), А не об авторах. Но также, в некоторых командах можно принять определенный уровень мастерства. Зависит от окружающей среды.
Обратите внимание , что с cut«s перспектива всех следующими одинакова: "-d ", '-d ', -d" ", -d' ', и -d\<space>: все формы непосредственно добавьте аргумент опции (пробел) к опции ( -d) и результату в той же самой строке к тому времени cutих видят: один аргумент, содержащий d, за которым следует пробел, после того как оболочка выполнила удаление кавычек
mklement0
1
@ ответ mklement0 должен быть ответ. Это самый полный на этой странице (хотя это комментарий).
Tresf
@QZSupport: Я ценю чувства и поддержку - это вдохновило меня опубликовать свой собственный ответ с дополнительной справочной информацией.
mklement0
1
Lol захватывающее открытие!
Гарри
4
Вы не можете сделать это легко с помощью cut, если данные имеют, например, несколько пробелов. Я нашел полезным нормализовать ввод для более легкой обработки. Одна хитрость заключается в использовании sed для нормализации, как показано ниже.
echo -e "foor\t \t bar"| sed 's:\s\+:\t:g'| cut -f2 #bar
scut , похожая на вырезку утилита (умнее, но медленнее сделанная мной), которая может использовать любое регулярное выражение perl в качестве ломающего токена. Разбивка на пробелах используется по умолчанию, но вы также можете разбивать регулярные выражения с несколькими символами, альтернативные регулярные выражения и т. Д.
scut -f='6 2 8 7'< input.file > output.file
поэтому приведенная выше команда разбивает столбцы на пробелах и извлекает столбцы (на основе 0) 6 2 8 7 в указанном порядке.
У меня есть ответ (я допускаю несколько запутанный ответ), который включает в себя sed, регулярные выражения и группы захвата:
\S* - первое слово
\s* - разделитель
(\S*) - второе слово - захвачено
.* - остальная часть линии
Как sedвыражение, потребность группы захвата экранировать, то есть \(и\) .
В \1возвращает копию захваченной группы, то есть второе слово.
$ echo "alpha beta gamma delta"| sed 's/\S*\s*\(\S*\).*/\1/'
beta
Когда вы смотрите на этот ответ, он несколько сбивает с толку, и, вы можете подумать, зачем беспокоиться? Ну, я надеюсь, что некоторые из них могут пойти "Ага!" и будет использовать этот шаблон для решения некоторых сложных задач извлечения текста с помощью одного sedвыражения.
man
страницы недостаточно. Давайте посмотрим: «-d delim
Используйтеdelim
в качестве символа разделителя полей вместо символа табуляции». (BSDcut
, но версия GNU и спецификация POSIX в значительной степени утверждают одно и то же). Использование оболочки для вызоваcut
- типичный случай - поэтому требует, чтобы вы знали, как обычно передавать пробел в качестве аргумента, используя синтаксис оболочки , что, возможно, неcut
является работой man-страницы. Однако примеры из реальной жизни всегда помогают, а в справочной странице GNU их нет.Ответы:
Где 2 - номер поля, которое вы хотите разделить пробелом.
источник
cut
, но вы можете с помощьюcuts
которых пытается «исправить» всеcut
ограничения: github.com/arielf/cutscut -d ' ' -f 3,6,9,12,15,18
без указания каждого номера?Обычно, если вы используете пробел в качестве разделителя, вы хотите рассматривать несколько пробелов как один, потому что вы анализируете выходные данные команды, выравнивающей некоторые столбцы с пробелами. (и поиск в Google это приводит меня сюда)
В этом случае одной
cut
команды недостаточно, и вам нужно использовать:Или
источник
Дополнять существующие полезные ответы; подсказка к QZ Поддержка за то, что я рекомендую опубликовать отдельный ответ:
Здесь действуют два разных механизма :
(а) является ли
cut
сам по себе требует разделителя (пространства, в данном случае) передается-d
возможности быть отдельным аргументом или является ли это приемлемо , чтобы добавить его непосредственно к-d
.(б) как оболочка обычно анализирует аргументы перед передачей их вызываемой команде.
(а) отвечает цитата из руководств POSIX для коммунальных услуг (выделено мое)
Другими словами: в этом случае, поскольку
-d
параметр-аргумент является обязательным , вы можете выбрать , указывать ли разделитель следующим образом :-d
.После того, как вы выбрали (s) или (d), именно строковый литеральный синтаксический анализ оболочки - (b) - имеет значение:
При подходе (ях) все следующие формы эквивалентны:
-d ' '
-d " "
-d \<space> # <space> used to represent an actual space for technical reasons
При подходе (d) все следующие формы эквивалентны:
-d' '
-d" "
"-d "
'-d '
d\<space>
Эквивалентность объясняется оболочкой строковой литеральной обработкой :
Все приведенные выше решения приводят к появлению точно такой же строки (в каждой группе) к тому времени, когда
cut
они их увидят :(s) :
cut
видит в-d
качестве своего собственного аргумента отдельный аргумент, содержащий пробел - без кавычек или\
префиксов !.(d) :
cut
видит-d
плюс пробел - без кавычек или\
префиксов! - как часть того же аргумента.Причина, по которой формы в соответствующих группах в конечном итоге идентичны, двояка, в зависимости от того, как оболочка анализирует строковые литералы :
'...'
воспринимается буквально и образует единый аргумент"..."
также формирует один аргумент, но подвергается интерполяции (расширяет ссылки на переменные, такие как$var
подстановки команд ($(...)
или`...`
) или арифметические расширения ($(( ... ))
).\
-цитирование отдельных символов :\
предшествующий одному символу этот символ интерпретируется как литерал.'...'
или"..."
или\
экземпляры) - таким образом, вызываемая команда никогда не видит символы кавычек .источник
Вы также можете сказать:
Обратите внимание, что после обратной косой черты есть два пробела.
источник
\
была моя первая попытка, и она сработала. Я согласен, что это менее очевидно по сравнению с' '
, но я уверен, что многие рады прочитать это здесь как подтверждение поведения. Для лучшего понимания смотрите комментарий @ mklement0 ниже.Я только что обнаружил, что вы также можете использовать
"-d "
:Тест
источник
'-d '
.cut
«s перспектива всех следующими одинакова:"-d "
,'-d '
,-d" "
,-d' '
, и-d\<space>
: все формы непосредственно добавьте аргумент опции (пробел) к опции (-d
) и результату в той же самой строке к тому времениcut
их видят: один аргумент, содержащий d, за которым следует пробел, после того как оболочка выполнила удаление кавычекВы не можете сделать это легко с помощью cut, если данные имеют, например, несколько пробелов. Я нашел полезным нормализовать ввод для более легкой обработки. Одна хитрость заключается в использовании sed для нормализации, как показано ниже.
источник
scut , похожая на вырезку утилита (умнее, но медленнее сделанная мной), которая может использовать любое регулярное выражение perl в качестве ломающего токена. Разбивка на пробелах используется по умолчанию, но вы также можете разбивать регулярные выражения с несколькими символами, альтернативные регулярные выражения и т. Д.
поэтому приведенная выше команда разбивает столбцы на пробелах и извлекает столбцы (на основе 0) 6 2 8 7 в указанном порядке.
источник
У меня есть ответ (я допускаю несколько запутанный ответ), который включает в себя
sed
, регулярные выражения и группы захвата:\S*
- первое слово\s*
- разделитель(\S*)
- второе слово - захвачено.*
- остальная часть линииКак
sed
выражение, потребность группы захвата экранировать, то есть\(
и\)
.В
\1
возвращает копию захваченной группы, то есть второе слово.Когда вы смотрите на этот ответ, он несколько сбивает с толку, и, вы можете подумать, зачем беспокоиться? Ну, я надеюсь, что некоторые из них могут пойти "Ага!" и будет использовать этот шаблон для решения некоторых сложных задач извлечения текста с помощью одного
sed
выражения.источник