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 osx 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=
.