Saída atual usando cal

6

Fui solicitado a enviar o dia atual usando o comando cal .

Até agora, descobri que antes da data atual há um símbolo _ . Decidi usar grep aqui: cal | grep '\b_*' , mas sai a semana inteira. Eu tentei várias variantes, mas não deu certo.

Na verdade, há também um caso, quando o dia atual tem apenas um dígito, então parece que eu tenho que usar tr -d ' ' aqui.

Não tenho ideia de como combinar todos esses comandos juntos.

    
por Welez 19.02.2017 / 20:45

3 respostas

8

Quando a saída do comando cal não é um terminal, aplica-se o sublinhado do homem pobre ao número do dia de hoje, que consiste em colocar um sublinhado e um caractere de retrocesso antes que cada caractere seja sublinhado. Você pode ver isso exibindo os caracteres visualmente ( ^H significa control-H , que é o caractere de retrocesso) :

cal | cat -A
cal | cat -vet

ou olhando para um despejo hexadecimal:

cal | hd
cal | od -t x1

Então, o que você precisa é detectar os caracteres sublinhados e gerá-los.

Com o GNU grep, existe uma maneira fácil de imprimir todas as correspondências de uma expressão regular: use a opção -o . Um caractere sublinhado é correspondido pela expressão regular estendida _^H. em que ^H é um caractere de retrocesso literal, não os dois caracteres ^ e H e . é o caractere a ser impresso. Em vez de digitar o caractere de retrocesso, você pode confiar no fato de que essa é a única maneira de usar sublinhados em sua saída. Portanto, basta detectar os sublinhados e deixar os espaços de retorno como caracteres não correspondentes.

cal | grep -o '_..'

Estamos próximos, mas a saída contém a sequência sublinhado-barra invertida e os dígitos estão em linhas separadas. Você pode remover todos os caracteres não digitados (e adicionar uma nova linha):

cal | grep -o '_..' | tr -d 0-9; echo

Como alternativa, você pode repetir o padrão _.. para corresponder a vários dígitos sublinhados. Isso deixa o sublinhado na saída, você pode usar tr ou sed para retirá-lo.

cal | grep -E -o '(_..)*'
cal | grep -E -o '(_..)*' | tr -d '\b_'
cal | grep -E -o '(_..)*' | sed 's/_.//g'

Você pode fazer isso com sed, mas não é completamente simples. O Sed oferece uma maneira fácil de imprimir apenas linhas correspondentes (use a opção -n para obter apenas linhas que são impressas explicitamente), mas nenhuma maneira direta de imprimir várias ocorrências de uma correspondência em uma linha. Uma maneira de resolver isso é aproveitar o fato de que há no máximo dois caracteres sublinhados e ter um comando s para transformar e gerar linhas contendo um único caractere sublinhado e outro para linhas com dois. Como antes, não corresponderei explicitamente aos backspaces.

cal | sed -n 's/.*_.\(.\)_.\(.\).*//p; s/.*_.\(.\).*//p'

Uma abordagem alternativa com sed, supondo que há apenas um segmento sublinhado em uma linha, é remover tudo antes e depois dele.

cal | sed -n 's/^[^_]*_/_/; s/\(_..\)[^_]*$//p'

Isso deixa os sublinhados; podemos removê-los com um terceiro substituto.

cal | sed -n 's/^[^_]*_/_/; s/\(_..\)[^_]*$//; s/_.//gp'
    
por 19.02.2017 / 23:13
10

A maneira correta de fazer isso é usar date :

% date +%d
19

O sublinhado que você vê não é um sublinhado, mas um caractere de controle mostrado pelo seu terminal. Se você realmente quiser usar cal , precisará descobrir qual é o caractere de controle e procurá-lo. Você pode usar isso usando algo como cal | xxd .

Outro problema é que cal apenas exibe esse caractere de controle quando stdout é um tty, então você precisa convencê-lo de que é um (considere script para isso).

    
por 19.02.2017 / 20:59
3

Eu não estou na frente de um comando GNU cal no momento, mas isso está mais próximo do que você quer:

cal | grep -Eo '_[[:digit:]]+' | sed 's/_//'

O grep -E diz para permitir expressões regulares estendidas (para a classe [[: digit:]]); o sinalizador -o diz para produzir apenas a parte correspondente; o comando sed remove o sublinhado.

Essa é a maneira de usar o cal + grep para fazê-lo, mas Chris disse , a maneira normal de obter o a data atual é com o comando date .

    
por 19.02.2017 / 22:16