используйте пробел в качестве разделителя с помощью команды вырезания
Вопрос
Я хочу использовать пробел в качестве разделителя с cut
команда.
Какой синтаксис я могу использовать для этого?
Решение
cut -d ' ' -f 2
Где 2 - номер поля, которое вы хотите разделить пробелом.
Другие советы
Обычно, если вы используете пробел в качестве разделителя, вы хотите рассматривать несколько пробелов как один, потому что вы анализируете выходные данные команды, выравнивающей некоторые столбцы с пробелами. (и поиск в Google приводит меня сюда)
В этом случае одной команды cut
недостаточно, и вам нужно использовать:
tr -s ' ' | cut -d ' ' -f 2
Или
awk '{print $2}'
Чтобы дополнить существующие полезные ответы;кончик шляпы, чтобы Поддержка 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\<space>
Эквивалентность объясняется оболочкаобработка строкового литерала:
Все приведенные выше решения приводят к точно такая же строка (в каждой группе) ко времени cut
видит их:
(с):
cut
видит-d
, как это собственный аргумент, за которым следует отдельный аргумент, содержащий пробел – без кавычек или\
префикс!.(г):
cut
видит-d
плюс пробел - без кавычек или\
префикс!- в рамках такой же аргумент.
Причина, по которой формы в соответствующих группах в конечном итоге идентичны, двояка: Как оболочка анализирует строковые литералы:
- Оболочка позволяет указывать литерал как есть через механизм под названием цитирование, который может занять несколько форм:
- одинарные кавычки струны:содержимое внутри
'...'
взят буквально и образует одинокий аргумент - двойные кавычки струны:содержимое внутри
"..."
также образует одинокий аргумент, но подлежит интерполяция (расширяет ссылки на переменные, такие как$var
, замены команд ($(...)
или`...`
) или арифметические разложения ($(( ... ))
). \
-цитирование индивидуальный персонажи:а\
предшествующий одному символу приводит к тому, что этот символ интерпретируется как литерал.
- одинарные кавычки струны:содержимое внутри
- Цитирование дополняется удаление цитаты, что означает, что после того, как оболочка проанализировала командную строку, она удаляет символы кавычек из аргументов (включая
'...'
или"..."
или\
экземпляры) - таким образом, вызываемая команда никогда не видит символы кавычек.
Вы также можете сказать
cut -d\ -f 2
обратите внимание, что после обратной косой черты есть два пробела.
Я только что обнаружил , что вы также можете используйте "-d "
:
cut "-d "
Test
$ cat a
hello how are you
I am fine
$ cut "-d " -f2 a
how
am
резать, утилита, подобная сокращению (я сделал ее умнее, но медленнее), которая может использовать любое регулярное выражение Perl в качестве токена взлома.Разрыв по пробелам используется по умолчанию, но вы также можете разбивать многосимвольные регулярные выражения, альтернативные регулярные выражения и т. д.
scut -f='6 2 8 7' < input.file > output.file
поэтому приведенная выше команда разбивает столбцы на пробелы и извлекает столбцы (от 0) 6 2 8 7 в этом порядке.
Вы не можете легко сделать это с помощью cut, если данные имеют, например, несколько пробелов. Я нашел полезным нормализовать ввод для более легкой обработки. Один из приемов - использовать sed для нормализации, как показано ниже.
echo -e "foor\t \t bar" | sed 's:\s\+:\t:g' | cut -f2 #bar
У меня есть ответ (признаю, несколько запутанный ответ), который включает в себяsed
, регулярные выражения и группы захвата:
\S*
- первое слово\s*
- разделитель(\S*)
- второе слово - захвачено.*
- остальная часть строки
Как sed
выражение, группу захвата необходимо экранировать, т.е. \(
и \)
.
А \1
возвращает копию захваченной группы, т.е.второе слово.
$ echo "alpha beta gamma delta" | sed 's/\S*\s*\(\S*\).*/\1/'
beta
Когда вы посмотрите на этот ответ, он несколько сбивает с толку, и вы можете подумать: зачем беспокоиться?Ну, я надеюсь, что некоторые могут пойти "Ага!" и будет использовать этот шаблон для решения некоторых сложных задач извлечения текста с одним sed
выражение.