cut- alguns exemplos de uso e linha de comando

Atualizado em: 29/09/2006



Sobre este documento

linhas de comando e scripts com uso do cut na edição de arquivos textos ou dados passados pelo pipe |.

alguns exemplos de linha de comando

CUT é indicado para arquivos ou variáveis com um separador comum entre os campos, ele trabalha com o conceito de delimitação de campos, pode ser espaço, tab, ponto, ponto e virgula ou qualquer outro, voce define qual é o delimitador, verifique no arquivo ou variável o que pode ser usado como delimitador, cut vai usa-lo como separador de camplos.

Quando não encontrar um delimitador, use outros processos para modificar o arquivo e adaptar um delimitador.

CUT também trabalha sem delimitador, neste caso pega a posição fixa das colunas informadas, tanto de inicio e fim de um conjunto de caracteres, não considera o deslocamento de palavras no texto.

Conheça também awk, na seleção de colunas e partes de texto tem muita semelhança com cut, exemplo de linha de comando nos dois para pegar o terceiro campo do dado recebido.

cut -d ";" -f3

awk -F; '{print $3}'

pegar somente parte de uma variável

Exemplo para pegar parte da variável minhavar, precisa criar a variável.

minhavar="letra6letra13letra20"

Nesta variável tenho 20 caracteres, para pegar somente os 15 primeiros.

echo $minhavar | cut -c0-15

Pegar somente os ultimos 10 caracteres

echo $minhavar | cut -c11-20

-c indica caracteres; -c0-15 indica para pegar da posição zero até 15 -c11-20 indica para pegar da posição 11 até 20

Funciona para posições fixa.

Faça testes, tem outras ferramentas mais indicada para variável com tamanho variável ou quando a informação muda de posição.

cut + rev

rev - reverte linhas ou arquivo

Quando não tem delimitadores ou tamanho definido, pode inverter a string para aplicar o cut a partir do inicio, depois precisa inverter o resultado para mostrar na mesma ordem.

Pegar os 4 últimos caracteres sem saber o tamanho da variável ou posição, neste exemplo retorna "este".

echo "pegarsomenteeste" | rev | cut -b-4 | rev

este

onde (rev) inverte a ordem, (cut -b-4) pega os 4 primeiros caracteres, o último (rev) inverte novamente para mostrar o resultado.

Mesmo resultado com sed, pegar as 4 posições do final da string.

echo "pegarsomenteeste" | sed -r 's/^.*(.{4})$/\1/'

Delimitadores

-d informa o delimitador para -f

Observe os exemplos abaixo, onde:

  -d" "  indica "espaço" como separador
  -d:   dois pontos como separador
  -d.   ponto como separador
  -d\_  underline como separador, igual -d"_"
  -d"_" undeline como separador, igual -d\_
  -d\   "espaço" como separador, igual a -d" "

O uso da \ significa para o cut usar o proximo caractere como separador, quando o separador for um "espaço" fica assim (-d\ ), fica a impressão que não tem delimitador, mas está indicando um "espaço" depois da \ como separador entre campos, portanto requer dois espaços, um como delimitador e outro como separador das diretivas do cut, para evitar erro de interpretação use aspas (-d" ") que tem o mesmo resultado de (-d\ ).

Opções válidas para definir o ponto como delimitador -d . -d. -d"." -d\. e mais algumas opções, citei como exemplo o ponto, a principio deve funcionar com qualquer caractere...

Voce decide quem é o delimitador, tudo depende do formato dos dados e de sua lógica. Faça a escolha do que vai usar como separador (delimitador), use ele depois da \ ou entre aspas.

Quando omitido o cut interpreta um tab como delimitador, dificilmente seus dados tem um tab entre os campos, portanto use -d mais um cracter que sirva para esta sepração, quando não for possível, faça em duas partes, aplique cut no resultado do prórpio cut, compare os resultados no exemplos a seguir.

Exemplo com o resultado do comando date.

Em instalação com idioma português o comando date retorna algo neste formato.

  date
  Seg Jun 12 19:21:40 BRT 2006

Passando este resultado com pipe (|), cut trabalhando com delimitador por espaço (-d" "), este resultado é dividido em 6 partes, onde -f1 pega Seg e -f6 pega 2006, faça testes com -f1 até -f6 para ver os resultados possíveis.

date | cut -d" " -f1

Retorna Seg

  Seg Jun 12 19:21:40 BRT 2006
   |   |  |  |         |   |
   |   |  |  |         |   |____ -f6 = 2006
   |   |  |  |         |________ -f5 = BRT
   |   |  |  |_ -f4 = 19:21:40
   |   |  |____ -f3 = 12
   |   |_______ -f2 = Jun
   |_________ -f1 = Seg

Com delimitador para dois pontos (-d:), o mesmo resultado acima é interpretado pelo cut como tendo 3 divisões, onde passa a obter os seguintes resultados:

     comando            resultado 
  date | cut -d: -f1    Seg Jun 12 19
  date | cut -d: -f2    21
  date | cut -d: -f3    40 BRT 2006 

date | cut -d: -f1

ou com a barra \, tem o mesmo resultado

date | cut -d\: -f1

Aplicando cut no resultado do cut.

date | cut -d " " -f4 | cut -d: -f2

Onde o primeiro (cut -d " " -f4 ) separa em colunas por espaços e pega a hora minutos e segundos em -f4 que está na quarta coluna. Passa para o segundo ( cut -d: -f2) agora seprando o resultado recebido em colunas e usando dois pontos para fazer itos, -f2 pega somente os minutos que está na segunda coluna. Neste caso não precisa desta volta toda, pode obter o mesmo resultado com (date | cut -d\: -f2), o exemplo de passagem para outro cut e alterar o delimitador serve somente como exemplo e mostrar esta possibilidade.

  Seg Jun 12 19:21:40 BRT 2006
  -----|------- |  ----|------
       |        |      |
       |        |      |____ -f6 = 40 BRT 2006
       |        |
       |        |___________ -f2 = 21
       |_________________ -f1 = Seg Jun 12 19

Percebeu como a escolha do delimintador -d modifica a divisão, -f só pode receber valores válidos dentro da divisão, entre a primeira e ultima.

Salvar este resultado em variável, como exemplo, salvar o nome do mes (Jun) em MVARMES.

MVARMES=$(date | cut -d" " -f2)

echo $MVARMES exibe o conteúdo da variável, serve para conferir, neste exemplo retorna Jun

Cuidado especial com o idioma, quando omitido trabalha com o configurado no sistema, também pode informar na linha de comando sem alterar a configuração do sistema, assim é possível pegar o resultado em outro idioma e sem modificar a configuração local.

echo `LC_ALL= LANG= date`

echo `LC_ALL=en_US LANG= date`

Resultado em idiona inglês mesmo em instalação configurada para pt_BR.

Mon Jun 12 20:12:54 BRT 2006

Compare os resultados abaixo, observe em que idioma retorna o dia da semana, faça tetes, copie estes exemplos e cole no console...

  echo `LC_ALL= LANG= date | cut -d" " -f1`
  Mon
  
  echo `LC_ALL=en_US LANG= date | cut -d" " -f1`
  Mon
  
  echo `LC_ALL=pt_BR LANG= date | cut -d" " -f1`
  Seg
  
  echo `date | cut -d" " -f1`
  Seg

Outro exemplo com ifconfig + grep + awk + cut

aplicar cut no resultado do comando abaixo para pegar somente o ultimo octeto do IP, pegar somente o 216 do resultado (addr:192.168.1.216)

ifconfig eth0 | grep "inet addr" | awk '{print $2}'

Este comando retorna

addr:192.168.1.216

definindo o ponto como delimitador (-d.) o 216 é a quarta posição (-f4), a linha de comando fica assim.

ifconfig eth0 | grep "inet addr" | awk '{print $2}' | cut -d. -f4

Retorna 216

  
  Neste exemplo, definindo ponto como delimitador (-d.), separa (addr:192.168.1.216)
  em 4 partes porque tem quatro pontos.
  -f pode variar de 1 a 4 para pegar os seguintes valores.
  
  addr:192.168.1.216
       |    |  |  |
       |    |  |  |
       |    |  |  |
       |    |  |  |_ -f4 = 216
       |    |  |____ -f3 = 1
       |    |_______ -f2 = 168 
       |__________ -f1 = addr:192
  
  Alterando o delimitador para dois pontos (-d:), divide o resultado em duas partes.
  
  ifconfig eth0 | grep "inet addr" | awk '{print $2}' | cut -d: -f2
  
  addr:192.168.1.216
   |    |
   |    |
   |    |
   |    |_ -f2 = 192.168.1.216
   |_____ -f1 = addr 

Outro exemplo com dois pontos, pegar o valor de RX (trafego), observe o resultado destas linhas de comando e o que retorna.

ifconfig eth0 | grep bytes

RX bytes:101269282 (96.5 Mb) TX bytes:3847222 (3.6 Mb)

ifconfig eth0 | grep bytes | awk '{print $2}'

bytes:101266665

ifconfig eth0 | grep bytes | awk '{print $2}' | cut -d: -f2

101266665

-f1 retorna; bytes

-f2 retorna o trafego, neste exemplo 101266665 bytes.

Pegar o valor de TX, altere awk para pegar coluna 6 (awk '{print $6}')

ifconfig eth0 | grep bytes | awk '{print $6}' | cut -d: -f2

Ideal para usar em script de verificação de trafego, consumo de banda....

Outros exemplos de delimitadores.

echo "usando em lugar do ponto ou espacos" | cut -d" " -f5

echo "usando_em_lugar_do_ponto_ou_espacos" | cut -d"_" -f5

echo "usando_em_lugar_do_ponto_ou_espacos" | cut -f5 -d"_"

Pegar mais de uma posição.

  pegar 3, 4 e 5
  
  echo "usando_em_lugar_do_ponto_ou_espacos" | cut -d"_" -f3,4,5
  lugar_do_ponto
  
  Ou definir para pegar da 3 até 5
  
  echo "usando_em_lugar_do_ponto_ou_espacos" | cut -f3-5 -d\_
  lugar_do_ponto
  
  echo "usando_em_lugar_do_ponto_ou_espacos" | cut -d"_" -f3,4,7
  lugar_do_espacos

Mais de um espaço entre palavaras, dependendo do comando e forma de trabalhar, pode eliminar espaços repetidos, alguns resultados com mais de um espaço pode ser exibido com somente um espaço. Para mostrar os espaços no resultado, precisa colocar a variável entre aspas, pode usar simbolos em volta da variável para exibir junto com o resultado, serve como referencia no console para ver e contar os espaços.

  MVAR="usando mais de um      espaço     entre     palavra"
  echo $MVAR
  usando mais de um espaço entre palavra
  
  Sem aspas acima elimina os espaços repetidos, com aspas abaixo exibe todos espaços.
  
  echo "$MVAR"
  usando mais de um      espaço     entre     palavra
  
  Mostrar resultado com simbolos em volta do resultado.
  
  MVAR2=`echo "$MVAR" | cut -c18-40`
  
  echo "$MVAR2"
        espaço     entre
  
  echo \""$MVAR2"\"
  "      espaço     entre "
  
  echo "($MVAR2)"
  (      espaço     entre )
  
  echo ":$MVAR2:"
  :      espaço     entre :
  
  echo "#$MVAR2#"
  #      espaço     entre #
  
  Outras formas que bash elimina os espaços repetidos.
  
  pegar o texto a partir da posição informada.
  
  echo \'${MVAR:20}\'
  
  Pegar caracteres a partir posição informada
  
  pegar 20 caracteres a partir da posição zero(inicio)
  echo \'${MVAR:0:20}\'
  'usando mais de um '
  
  pegar 40 caracteres a partir da posição 18
  echo \"${MVAR:18:40}\"
  " espaço entre palavra"

valor da coluna em variável

Exemplo de script que pega a coluna definida em variável

Parte de script que utilizo para matar varios PID do mesmo processo, o contador MKIL tem a quantidade de processos e MVAR o PID, esta variável MKIL é utilizada no cut para indicar qual coluna pegar, veja onde entra (cut -d' ' -f$MKIL)

  PROCESSOS=$(ps ax|grep "python"|awk '{print $1}')
  MQTDE=`echo $PROCESSOS | wc -w`
  while [ $MQTDE -ne 0 ] ; do
    MKIL=`echo $MQTDE`
    while [ $MKIL -ne 0 ] ; do
       echo "numero do contador atual $MKIL"
       MVAR2=`echo $PROCESSOS | cut -d' ' -f$MKIL`
       echo "matando $MVAR2 " /tmp/kilteste.txt
       kill -9 $MVAR2
       sleep 5
       MKIL=$[$MKIL-1]
     done
  #zerar para novo teste
  PROCESSOS=$(ps ax|grep "python"|awk '{print $1}')
  MQTDE=`echo $PROCESSOS | wc -w`
  MKIL=`echo $MQTDE`
  done

cut pegando dados em arquivos

Aplique diretamente em arquivos para pegar partes da linha ou colunas.

Exibir somente os 5 primeiros caracteres de cada linha

cut -c-5 /tmp/comandos.txt

Salvar o resultado em arquivo.

cut -c-5 /tmp/comandos.txt >> comandos5.txt

Exibir a coluna 5 e usando como delimitador o espaço.

cut -d" " f5 /tmp/comandos.txt

Sem delimitador, pegar posições especificas.

Pegar somente uma posição, caractere na posição 11

  echo "usando_em_lugar_do_ponto_ou_espacos" | cut -c 11
  l

Pegar tudo menos as posições do inicio, cortar caracteres do inicio, exemplo para pegar tudo menos as 4 primeiras posições, ou se preferir, pegar da 5 posição em diante.

  echo "usando_em_lugar_do_ponto_ou_espacos" | cut -c 5-
  do_em_lugar_do_ponto_ou_espacos

Invertendo, pegar somente os caracteres iniciais, exemplo para pegar somente os 5 primeiros.

  echo "usando_em_lugar_do_ponto_ou_espacos" | cut -c1-5
  usand

Trabalhando com byte -b, dependendo da origem dos dados o resultado é o mesmo que -c, mas um caractere não é igual a um byte, portanto fique atento a origem dos dados, neste exemplo com -b o resultado é igual com -c, na posição 12 tem a letra (u).

Pegar somente o caracter na posição 12, independente do separador.

  echo "usando_em_lugar_do_ponto_ou_espacos" | cut -b 12
  u
  echo "usando em lugar do ponto ou espacos" | cut -b 12
  u

pegar os 12 caracteres iniciais, espaço também é tradado como caracter...

  echo "usando_em_lugar_do_ponto_ou_espacos" | cut -b1-12
  usando_em_lu
  echo "usando em lugar do ponto ou espacos" | cut -b1-12
  usando em lu
  echo "usando_em_lugar_do_ponto_ou_espacos" | cut -b1-5
  usand

man cut

  NOME
         cut - remove seções de cada linha dos arquivos
  
  SINOPSE
         cut  {-b  lista-de-bytes,  --bytes=byte-list} [-n] [--help] [--version]
         [arquivo...]
  
         cut  {-c  lista-de-caracteres,  --characters=character-list}   [--help]
         [--version] [arquivo...]
  
         cut  {-f  lista-de-campos,  --fields=field-list}  [-d delimitador] [-s]
         [--delimiter=delim]     [--only-delimited]     [--help]     [--version]
         [arquivo...]
  
     OPÇÕES
         Byte, caracter, e campo são um ou mais números ou faixas (dois  números
         separados  por uma barra) separados por vírgulas. O primeiro byte, car-
         acter e campo são  numerados  como  1.  Faixas  incompletas  podem  ser
         definidas  com:  `-m' significa `1-m'; `n-' significa de  `n' até o fim
         da linha ou último campo.
  
         -b, --bytes lista-de-bytes
                Lista somente os  bytes  listados  nas  posições  definidas  por
                lista-de-bytes.   Tabulações  e  retrocessos  são  tratados como
                qualquer outro caracter; ocupando 1 byte cada.
  
         -c, --characters lista-de-caracteres
                Lista somente caracteres listados   em  lista-de-caracteres.   O
                mesmo  que  -b  por  hora,  porém  a  internacionalização poderá
                alterar esta funcionalidade. Tabulações e retrocessos são trata-
                dos como qualquer outro caracter; ocupando 1 byte cada.
  
         -f, --fields lista-de-campos
                Lista somente os campos listados na lista-de-campos.  Campos são
                separados por um TAB por padrão.
  
         -d, --delimiter delimitador
                Para uso com -f, onde os campos são separados pelo primeiro car-
                acter em delimitador ao invés de TAB.
  
         -n     Não  separa  caracteres  que  ocupem  mais de um byte (ainda não
                operacional).
  
         -s, --only-delimited
                Para -f, não imprime as linhas que não contenham o caracter sep-
                arador de campo.
  

Indicações

cut - FAQ com mensagens da Linux-br
http://www.zago.eti.br/cut.txt

Página principal sobre script em geral (FAQ)
http://www.zago.eti.br/script/A-menu-scripts.html

Página principal deste site (FAQ)
http://www.zago.eti.br/menu.html