- Команда cut в Linux
- Как использовать команду cut
- Как обрезать по полю
- Как вырезать по разделителю
- Чем дополнить подборку
- Как указать разделитель вывода
- Как обрезать по байтам и символам
- Примеры вырезок
- Получите список всех пользователей
- Посмотреть 10 наиболее часто используемых команд
- Выводы
- Как указать больше пробелов для разделителя, используя cut?
- 12 ответов
- Короче/более простое решение: используйте cuts (на стероидах я писал)
Команда cut в Linux
В системах Linux и Unix доступно множество утилит, позволяющих обрабатывать и фильтровать текстовые файлы. cut — это утилита командной строки, которая позволяет вырезать части строк из указанных файлов или данных, передаваемых по конвейеру, и выводить результат на стандартный вывод. Его можно использовать для вырезания частей строки по разделителю, позиции байта и символу.
В этой статье мы покажем вам, как использовать команду cut на практических примерах и подробных объяснениях наиболее распространенных параметров.
Как использовать команду cut
Синтаксис команды cut следующий:
Параметры, которые указывают cut следует ли использовать разделитель, позицию байта или символ при вырезании выбранных частей строк, следующие:
- -f ( —fields=LIST ) — Выбрать, указав поле, набор полей или диапазон полей. Это наиболее часто используемый вариант.
- -b ( —bytes=LIST ) — Выбрать, указав байт, набор байтов или диапазон байтов.
- -c ( —characters=LIST ) — Выбрать, указав символ, набор символов или диапазон символов.
Вы можете использовать один и только один из перечисленных выше вариантов.
- -d ( —delimiter ) — укажите разделитель, который будет использоваться вместо разделителя по умолчанию «TAB».
- —complement — Дополнить выбор. При использовании этой опции cut отображает все байты, символы или поля, кроме выбранных.
- -s ( —only-delimited ) — по умолчанию cut печатает строки, не содержащие символа разделителя. Когда используется эта опция, cut не печатает строки, не содержащие разделителей.
- —output-delimiter — По умолчанию cut использует разделитель ввода в качестве ограничителя вывода. Этот параметр позволяет указать другую строку разделителя вывода.
Команда cut может принимать ноль или более входных имен ФАЙЛОВ. Если FILE не указан или если FILE — — , cut будет читать из стандартного ввода.
Аргумент LIST переданный параметрам -f , -b и -c , может быть целым числом, несколькими целыми числами, разделенными запятыми, диапазоном целых чисел или несколькими диапазонами целых чисел, разделенными запятыми. Каждый диапазон может быть одним из следующих:
- N -ое поле, байт или символ, начиная с 1.
- N- от N-го поля, байта или символа, до конца строки.
- NM от N-го до M-го поля, байта или символа.
- -M от первого до M-го поля, байта или символа.
Как обрезать по полю
Чтобы указать поля, которые следует вырезать, вызовите команду с параметром -f . Если не указано иное, разделителем по умолчанию является «ТАБЛИЦА».
В приведенных ниже примерах мы будем использовать следующий файл. Поля разделены табуляцией.
245:789 4567 M:4540 Admin 01:10:1980 535:763 4987 M:3476 Sales 11:04:1978
Например, чтобы отобразить 1-е и 3-е поля, вы должны использовать:
245:789 M:4540 535:763 M:3476
Или, если вы хотите отображать с 1-го по 4-е поля:
245:789 4567 M:4540 Admin 535:763 4987 M:3476 Sales
Как вырезать по разделителю
Чтобы вырезать по разделителю, вызовите команду с параметром -d , за которым следует разделитель, который вы хотите использовать.
Например, чтобы отобразить 1-е и 3-е поля с использованием «:» в качестве разделителя, вы должны ввести:
245:4540 Admin 01 535:3476 Sales 11
В качестве разделителя можно использовать любой одиночный символ. В следующем примере мы используем пробел в качестве разделителя и печатаем 2-е поле:
echo "Lorem ipsum dolor sit amet" | cut -d ' ' -f 2
Чем дополнить подборку
Чтобы дополнить список полей выбора, используйте параметр —complement . Это напечатает только те поля, которые не выбраны с помощью опции -f .
Следующая команда распечатает все поля, кроме 1-го и 3-го:
cut test.txt -f 1,3 --complement
4567 Admin 01:10:1980 4987 Sales 11:04:1978
Как указать разделитель вывода
Чтобы указать разделитель вывода, используйте параметр —output-delimiter . Например, чтобы установить разделитель вывода на _ вы должны использовать:
cut test.txt -f 1,3 --output-delimiter='_'
245:789_M:4540 535:763_M:3476
Как обрезать по байтам и символам
Прежде чем идти дальше, давайте проведем различие между байтами и символами.
Один байт составляет 8 бит и может представлять 256 различных значений. Когда был установлен стандарт ASCII, он учитывал все буквы, цифры и символы, необходимые для работы с английским языком. Таблица символов ASCII состоит из 128 символов, и каждый символ представлен одним байтом. Когда компьютеры стали доступны во всем мире, технологические компании начали вводить новые кодировки символов для разных языков. Для языков, содержащих более 256 символов, простое сопоставление 1 к 1 было невозможно. Это приводит к различным проблемам, таким как совместное использование документов или просмотр веб-сайтов, и требовался новый стандарт Unicode, который может обрабатывать большинство мировых систем письма. UTF-8 был создан для решения этих проблем. В UTF-8 не все символы представлены 1 байтом. Символы могут быть представлены от 1 до 4 байтов.
Параметр -b ( —bytes ) указывает команде вырезать разделы из каждой строки, указанной в заданных позициях байтов.
В следующих примерах мы используем символ ü который занимает 2 байта.
echo 'drüberspringen' | cut -b 5
Выберите 5-й, 9-й и 13-й байты:
echo 'drüberspringen' | cut -b 5,9,13
Выберите диапазон от 1-го до 5-го байта:
echo 'drüberspringen' | cut -b 1-5
На момент написания этой статьи версия cut входящая в состав GNU coreutils, не имела возможности вырезать по символам. При использовании параметра -c команда cut ведет себя так же, как и при использовании параметра -b .
Примеры вырезок
Команда cut обычно используется в сочетании с другими командами через трубопровод. Вот несколько примеров:
Получите список всех пользователей
Вывод команды getent passwd передается в cut , который печатает первое поле с использованием : качестве разделителя.
Посмотреть 10 наиболее часто используемых команд
В следующем примере cut используется для удаления первых 8 байтов из каждой строки вывода команды history .
history | cut -c8- | sort | uniq -c | sort -rn | head
Выводы
Команда cut используется для отображения выбранных полей из каждой строки заданных файлов или стандартного ввода.
Хотя это очень полезно, cut имеет некоторые ограничения. Он не поддерживает указание более одного символа в качестве разделителя и не поддерживает несколько разделителей.
Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.
Как указать больше пробелов для разделителя, используя cut?
Можно ли указать разделитель полей для большего количества пробелов с помощью команды cut? (например, «+)? Например: В следующей строке мне нравится достигать значения «3744», какой полевой разделитель я должен сказать?
$ps axu | grep jboss jboss 2574 0.0 0.0 3744 1092 ? S Aug17 0:00 /bin/sh /usr/java/jboss/bin/run.sh -c example.com -b 0.0.0.0
cut -d’ ‘ не то, что я хочу, для него только для одного пробела. awk — это не то, что я ищу, но как сделать с «cut»? спасибо.
Не имеет прямого отношения к конкретному вопросу, но вместо ps + grep вы можете использовать pgrep который доступен в большинстве современных дистрибутивов. Он вернет результат именно в той форме, в которой он вам нужен.
12 ответов
Фактически awk — это именно тот инструмент, который вы должны изучать:
или вы можете полностью отключить grep , так как awk знает о регулярных выражениях:
Но если для какой-то причудливой причины вы действительно не можете использовать awk , вы можете сделать другие более простые вещи, например, сначала свернуть все пробелы до одного пробела:
ps axu | grep '[j]boss' | sed 's/\s\s*/ /g' | cut -d' ' -f5
Этот трюк grep , кстати, является аккуратным способом получить только процессы jboss , а не grep jboss (например, для варианта awk ).
Процесс grep будет иметь литерал grep [j]boss в своей команде процесса, поэтому его не поймает сам grep , который ищет класс символов [j] , за которым следует boss .
Это отличный способ избежать парадигмы | grep xyz | grep -v grep , которую используют некоторые люди.
Я продолжаю учиться и забывать трюк с Грепом. Спасибо за мое последнее напоминание. Может быть, на этот раз он будет придерживаться. Но я бы не стал на это ставить.
@ Майкл, вы должны создать где-нибудь задание cron, чтобы отправлять вам этот совет (и, возможно, другие) раз в месяц 🙂
Для этой последней команды sed вы должны быть в состоянии сделать \s+ для «одного или нескольких пробелов» вместо \s\s* который говорит «пробел, за которым следует ноль или более пробелов»
Это отличный ответ, но ОП спросил, как это сделать с помощью cut, поэтому я считаю, что stackoverflow.com/a/29685565/869951 заслуживает большего доверия, чем в настоящее время.
Оливер, иногда лучший ответ на вопрос «как мне сделать X с Y?» «Не используйте Y, используйте вместо Z». Поскольку ОП принял этот ответ, я, вероятно, убедил их в этом 🙂
awk вариант, вероятно, лучший способ пойти, но вы также можете использовать cut , если вы сначала сжимаете повторы с помощью tr :
ps axu | grep jbos[s] | tr -s ' ' | cut -d' ' -f5 # ^^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^ # | | | # | | get 5th field # | | # | squeeze spaces # | # avoid grep itself to appear in the list
Мне нравится использовать команду tr -s для этого
ps aux | tr -s [:blank:] | cut -d' ' -f3
Это сжимает все пробелы до 1 пробела. Таким образом, говорят, что сокращение использования пространства в качестве разделителя соблюдается, как и ожидалось.
Я думаю, что это должен быть ответ, это ближе к запросу OP (попросил использовать вырезать). Этот подход медленнее на 5-10% по сравнению с подходом awk (потому что есть еще один канал, который нужно обработать с помощью tr), но в целом это будет неактуально.
Я собираюсь назначить tr -s [:blank:] лучшим ответом.
Почему мы хотим использовать разрез? У этого есть волшебная команда, которая говорит «мы хотим, чтобы третье поле и каждое поле после него, опуская первые два поля»
cat log | tr -s [:blank:] |cut -d' ' -f 3-
Я не верю, что есть эквивалентная команда для awk или perl split, где мы не знаем, сколько полей будет, т.е. помещаем третье поле через поле X.
Один из способов сделать это:
$ps axu | grep jboss | sed 's/\s\+/ /g' | cut -d' ' -f3
заменить несколько последовательных пробелов на один.
\s является расширением GNU sed. В OS X вы можете передать флаг -E в sed для включения расширенных регулярных выражений, а затем использовать [[:space:]] вместо \s , например: sed -E ‘s/[[:space:]]+/ /g’
Короче/более простое решение: используйте cuts (на стероидах я писал)
ps axu | grep '[j]boss' | cuts 4
Обратите внимание, что индексы полей cuts начинаются с нуля, поэтому 5-е поле указано как 4
И даже короче (не используя вырезать) это:
Лично я склонен использовать awk для таких заданий. Например:
ps axu| grep jboss | grep -v grep | awk ''
Это можно сжать до ps axu | awk ‘/[j]boss/
Если вы хотите выбрать столбцы из вывода ps, есть ли причина не использовать -o?
ps ax -o pid,vsz ps ax -o pid,cmd
Минимальная выделенная ширина столбца, без заполнения, только один разделитель пробела.
ps ax --no-headers -o pid:1,vsz:1,cmd 3443 24600 -bash 8419 0 [xfsalloc] 8420 0 [xfs_mru_cache] 8602 489316 /usr/sbin/apache2 -k start 12821 497240 /usr/sbin/apache2 -k start 12824 497132 /usr/sbin/apache2 -k start
Pid и vsz, учитывая ширину 10 символов, 1 разделитель пробелов.
ps ax --no-headers -o pid:10,vsz:10,cmd 3443 24600 -bash 8419 0 [xfsalloc] 8420 0 [xfs_mru_cache] 8602 489316 /usr/sbin/apache2 -k start 12821 497240 /usr/sbin/apache2 -k start 12824 497132 /usr/sbin/apache2 -k start
oldpid=12824 echo "PID: $" echo "Command: $(ps -ho cmd $)"
В качестве альтернативы всегда есть perl:
ps aux | perl -lane 'print $F[3]'
Или, если вы хотите получить все поля, начинающиеся с поля № 3 (как указано в одном из ответов выше):
ps aux | perl -lane 'print @F[3 .. scalar @F]'
Это не работает с выводом lsof Я попробовал lsof|perl -lane ‘print $F[5]’ иногда он получает 5-й столбец, иногда 6-й
Я думаю, что вопрос был только в том, как использовать разделители, которые могут содержать различное количество пробелов. Для этого ответ был верным.
Мой подход заключается в том, чтобы сохранить PID в файле в /tmp и найти правильный процесс, используя -S для ssh . Это может быть неправильно, но работает на меня.
#!/bin/bash TARGET_REDIS=$ PROXY="proxy.somewhere.com" LOCAL_PORT=$ if [ "$1" == "stop" ] ; then kill 'cat /tmp/sshTunel$-pid' exit fi set -x ssh -f -i ~/.ssh/aws.pem centos@$PROXY -L $LOCAL_PORT:$TARGET_REDIS:6379 -N -S /tmp/sshTunel$LOCAL_PORT ## AWS DocService dev, DNS alias # SSH_PID=$! ## Only works with & SSH_PID='ps aux | grep sshTunel$ | grep -v grep | awk ''' echo $SSH_PID > /tmp/sshTunel$-pid
SSH_PID подходом может быть запрос SSH_PID непосредственно перед его уничтожением, поскольку файл может устареть и уничтожить неправильный процесс.