Você está tentando contar o número total de arquivos em um diretório nomeado pelo campo 6 no arquivo freeze2-1.out, mas apenas onde "Rawdata" aparece em algum lugar na linha desse arquivo.
O principal erro no seu post inicial foi simplesmente um de lógica ou posicionamento; você estava pedindo a wc -l
para contar as linhas individuais dentro do loop dentro de perguntar pelo número total de linhas que o loop geral fornecia. Isso é o que a maioria das respostas existentes está corrigindo.
Eu criei um arquivo de amostra freeze2-1.out para que eu pudesse "tocar junto em casa"; aqui está o que eu coloco:
Rawdata 2 3 4 5 file1
Rawdata 2 3 4 5 file2
Rawdata 2 3 4 5 file3
Eu também preenchei um diretório relativo chamado "appdata / frozen_files" com nomes de diretório baseados no campo 6 acima. Observe que seu caminho real é um caminho absoluto começando com / appdata / frozen_files. Coloquei 1 arquivo no arquivo1, 2 no arquivo2 e 3 no arquivo3, para um total de 6 arquivos.
O primeiro aprimoramento que sugiro é combinar o grep
e o awk
, já que o awk pode fazer a correspondência de padrões. RomanPerekhrest também fez isso em sua resposta:
awk '/Rawdata/ { print $6 }' freeze2-1.out
A saída da amostra é então:
file1
file2
file3
Vou apontar aqui que, como o awk divide os campos com base em espaços, tabulações e novas linhas, imprimir especificamente no campo 6 implica que cada linha de saída terá uma palavra sem espaços.
Existem algumas maneiras de contar o número de arquivos em um diretório. Usar ls -1 | wc -l
é um caminho, mas falha em um caso muito particular em que um nome de arquivo possui uma nova linha incorporada; você poderia criar tal arquivo manualmente com touch $'file\nname'
. Como o awk está lendo linhas de entrada delimitadas por novas linhas, não vamos encontrar esse caso especial aqui, mas eu queria mencioná-lo. Por exemplo:
# create the file
$ touch $'file\nname'
# check the listing; looks okay so far
$ ls -1
appdata
file?name
freeze2-1.out
# count them up
$ ls -1 | wc -l
4
# woops! should be 3!
Por esse motivo, demonstrarei dois outros métodos para contar os arquivos em um diretório.
O primeiro método usa o set
embutido para pegar seus argumentos e convertê-los em argumentos posicionais nomeados por $ 1, $ 2, $ 3, etc.
$ sum=0
$ for file in $(awk '/Rawdata/ { print $6 }' freeze2-1.out)
do
set -- "appdata/frozen_files/${file}/"*
sum=$((sum + $#))
done
$ echo "$sum"
6
Isso inicializa um contador sum
para zero e, em seguida, percorre os nomes dos arquivos da saída awk. Ele chama set
com o caminho entre aspas para o diretório, seguido pelo *
shell glob, que é expandido para todos os arquivos (não ocultos) desse diretório. Isso corresponde ao comportamento ls -1
de excluir arquivos ocultos (aqueles que começam com um ponto). O número de parâmetros é dado pela variável especial $#
, que adicionamos dentro do loop a sum
, depois imprimimos no final.
Um segundo método, para shells que suportam arrays, é colocar os nomes de arquivos em globalização em uma matriz e, em seguida, contar os elementos da matriz:
$ sum=0
$ for file in $(awk '/Rawdata/ { print $6 }' freeze2-1.out )
do
n=("appdata/frozen_files/${file}"/*)
sum=$((sum + ${#n[@]}))
done
$ echo "$sum"
6