linhas de comando e scripts com uso do cut na edição de arquivos textos ou dados passados pelo pipe |.
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}'
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.
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/'
-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"
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
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
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
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.