Extraindo Saída no Shell

1

Quando estou fazendo

ls -la |grep -e Aug

Estou recebendo a saída como

-rw-r--r--    1 root           staff   454 Oct 15 18:35 Aug.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 25 04:00 abc7.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 26 07:00 def7.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 27 10:00 ghi7.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 28 13:00 jkl7.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 29 16:00 mno7.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 30 19:00 pqr7.txt

Eu só quero listar os arquivos que são criados em agosto e não o primeiro arquivo que é criado em outubro, mas tem o nome Aug nele. Abaixo deve estar a saída

-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 25 04:00 abc7.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 26 07:00 def7.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 27 10:00 ghi7.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 28 13:00 jkl7.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 29 16:00 mno7.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 30 19:00 pqr7.txt

Além disso, quero considerar o mês como entrada do usuário não o valor codificado.

    
por Prashast 16.10.2017 / 03:42

2 respostas

2

Você deve considerar alternativas para analisar ls , que é repleto de múltiplas armadilhas . Mas como o seu principal interesse aqui é como filtrar por coluna, e seu objetivo final pode não ser analisar ls , vou em frente e continuo com o exemplo que você está usando (que usa ls ) . Por favor, não leve isso para dizer que a saída de ls é uma boa coisa a fazer, no entanto. Geralmente não é bom fazer isso.

Quando você usa grep para Aug , está pesquisando em qualquer lugar em uma linha. Realmente você não deseja selecionar linhas que contenham Aug em qualquer lugar, mas apenas aquelas que o contêm como o texto completo e exato de sua sexta coluna. Embora você possa fazer isso com grep , é muito mais fácil e natural com awk :

ls -la | awk '$6 == "Aug"'

Se por algum motivo você realmente quiser fazer isso com grep , você pode:

ls -la | grep -E '(\S+\s+){5}Aug\s'

Você está também interessado na filtragem de linhas cuja sexta coluna é igual para um valor que foi lido em uma variável de shell month . Você observou que isso não funciona :

ls -la | awk '$6 == "$month"'   # does not work

O motivo que não funciona é que as citações simples em todo o O script AWK $6 == "$month" impede que o shell execute expansão de parâmetro em $month para substituí-lo por seu valor. O texto $month é passado como é para awk , que não é o que você deseja. As variáveis do AWK e as variáveis do shell são completamente separadas. Uma maneira simples e limpa de resolver esse problema é inicializar uma variável AWK do variável de shell usando a opção awk do comando -v :

ls -la | awk -v m="$month" '$6 == m'

Você poderia nomear sua variável AWK da mesma forma que sua variável de shell, se quiser. Esta é uma escolha razoável em casos como este, onde eles representam a mesma coisa. Eu nomeei a variável AWK m , para ilustrar como as variáveis shell e AWK são separadas e também para evitar confusão. (Para scripts AWK longos ou complicados, ou aqueles com muitas variáveis, você provavelmente desejaria nomear a variável mais descritivamente do que apenas m , mas neste caso nenhuma legibilidade é sacrificada.)

Linkei acima para tópicos no manual de referência do Bash porque você marcou sua pergunta e o shell padrão em todas as versões, exceto as mais antigas do SO X (agora chamado macOS) é bash . Em versões muito antigas, era tcsh .

Como observação, você mencionou que usou o valor de month como entrada com o comando read month . Quando você usa o comando read do seu shell, você deve quase sempre passar o -r flag e, assim, escrever read -r month . Apenas omita -r se você quiser o comando read traduzir \ escapes na entrada que recebe (o que você praticamente nunca deseja). Você também pode querer usar IFS= read -r month , então os espaços em branco iniciais e finais não são removidos. Nesse caso, no entanto, é provável que você queira removê-lo e, assim, omitir IFS= .

    
por 16.10.2017 / 04:01
0

Este trabalhou para mim

ls -al | awk '$6 == "Aug" {print}'
    
por 16.10.2017 / 04:01

Tags