shell para imprimir a data de modificação de todos os nomes de diretórios padrão de correspondência

4

Eu quero escrever um programa shell que passe por todas as pastas cujos nomes correspondam a um padrão como este:

sudo sh  shell.sh   pub 

Quando executado, o script procurará todas as pastas cujo nome contenha pub e imprima sua data de modificação. Desejo ter um código que irá imprimir resultados como nesta imagem: Eu tenho esse código, mas ele não está me dando o resultado que eu espero.

echo  'the folder '$1' was modified at ';
 find  -type d -name 'kam*'  -exec stat -c '%y %n' '{}' \;

Eu preciso percorrer todas as pastas e enviar o texto echo 'the file '$1' was modified at '; e imprimir a data como na imagem.

Eu gostaria de um resultado como este:

netcom@hotspot:~$ bash script.sh testRegex Pub
the folder testRegex was modified on may 15 01:19
 the folder Public was modified on may 19 01:19 
  the folder Pubos was modified on may 19 01:19 
    
por Muh 07.06.2018 / 09:18

4 respostas

6

Você pode usar o find para imprimir tudo:

for pattern
do
    find . -type d -name "*$pattern*" -printf 'The folder %P was modified on %t\n'
done

for pattern; do ... done faz um loop sobre todos os argumentos, com a variável pattern definida para cada argumento.

Com find , %P e %t , forneça o caminho para o arquivo e a hora da modificação em -printf .

    
por muru 07.06.2018 / 09:42
5

Você pode usar bash com a opção globstar ativada como no script a seguir:

#!/bin/bash
shopt -s globstar
for i
  do for k in **/"$i"*/
    do stat -c "the folder %n was modified on %y" "$k"
  done
done

Salve como script , torne-o executável com chmod +x script e chame da forma que você quiser:

bash /path/to/script testRegex Pub

Observe que isso pesquisará, por exemplo, Pub* , se você realmente deseja corresponder a *Pub* , altere **/"$i"*/ para **/*"$i"*/ . Se você quiser reduzir o timestamp, tente adicionar | sed 's/:[^:]*$//' ao final da linha do stat . Você também deve tentar %N em vez de %n , especialmente quando se trata de nomes de diretório com espaços em que esse formato é preferível.

Se você quiser um controle mais refinado sobre o formato de data, use date e substitua a linha do stat pelo seguinte:

do date -d@$(stat -c%Y "$k") +"the folder $k was modified on %b %d %R"

Você pode usar as sequências de formato date usuais explicadas em man date , essa aqui imprime, por exemplo. May 15 01:19 conforme solicitado.

Por último, mas não menos importante, para imprimir bastante a saída de qualquer uma das opções acima, você pode inserir uma tabulação após o nome do diretório e usar column da seguinte forma:

#!/bin/bash
shopt -s globstar
for i
  do for k in **/"$i"*/
    do date -d@$(stat -c%Y "$k") +"the folder $k%twas modified on %b %d %R"
  done
done | column -ts$'\t'

Exemplo de execução

$ tree
.
├── 1
│   └── 1
│       └── 1
├── 1something
└── 2
    └── 1
$ bash -O globstar -c 'for i; do for k in **/"$i"*/; do stat -c "the folder %n was modified on %y" "$k"; done; done' _ 1
the folder 1/ was modified on 2018-06-07 09:45:28.098693507 +0200
the folder 1/1/ was modified on 2018-06-07 09:45:28.098693507 +0200
the folder 1/1/1/ was modified on 2018-06-07 09:45:28.098693507 +0200
the folder 1something/ was modified on 2018-06-07 09:55:36.066531665 +0200
the folder 2/1/ was modified on 2018-06-07 09:45:28.098693507 +0200
$ bash -O globstar -c 'for i; do for k in **/"$i"*/; do stat -c "the folder %n was modified on %y" "$k" | sed 's/:[^:]*$//'; done; done' _ 1
the folder 1/ was modified on 2018-06-07 09:45
the folder 1/1/ was modified on 2018-06-07 09:45
the folder 1/1/1/ was modified on 2018-06-07 09:45
the folder 1something/ was modified on 2018-06-07 09:55
the folder 2/1/ was modified on 2018-06-07 09:45
$ bash -O globstar -c 'for i; do for k in **/"$i"*/; do date -d@$(stat -c%Y "$k") +"the folder $k was modified on %b %d %R"; done; done' _ 1
the folder 1/ was modified on Jun 07 09:45
the folder 1/1/ was modified on Jun 07 09:45
the folder 1/1/1/ was modified on Jun 07 09:45
the folder 1something/ was modified on Jun 07 09:55
the folder 2/1/ was modified on Jun 07 09:45
$ bash -O globstar -c 'for i; do for k in **/"$i"*/; do date -d@$(stat -c%Y "$k") +"the folder $k%twas modified on %b %d %R"; done; done | column -ts'"$'\t'" _ 1
the folder 1/           was modified on Jun 07 09:45
the folder 1/1/         was modified on Jun 07 09:45
the folder 1/1/1/       was modified on Jun 07 09:45
the folder 1something/  was modified on Jun 07 09:55
the folder 2/1/         was modified on Jun 07 09:45
    
por dessert 07.06.2018 / 10:06
4

O comando find pode fazer o que você precisa com uma linha

Você pode dar uma olhada na ação printf em find
Ver man find para detalhes dos parâmetros de printf

Exemplo

find /PATH/TO/SCAN -type d -iname '*pub*' -printf "%p %TY-%Tm-%Td %TH:%TM\n"

-type d        : search for folders
-iname '*pub*' : find the pattern case insensitive
%p             : display path of found folder
%TY            : time Year 
%Tm            : time month
%Td            : time day
%TH            : time hour
%TM            : time minutes
%TS            : time seconds


Para mais informações Página oficial para GNU find
25 exemplos práticos da descoberta comando

    
por cmak.fr 07.06.2018 / 09:45
2

Aqui está uma pequena variação, que faz uso de -regex em vez de -names :

find . -type d -regex ".*\($1\).*$" -printf 'The folder %P was modified on %Tb %Td %TH:%TM\n'

Isso pode ser um script de linha única ou, melhor ainda, uma função. Chame assim:

./finder.sh 'Vid\|Doc'

Isso torna a abordagem mais idiomática, grep .

    
por Sergiy Kolodyazhnyy 07.06.2018 / 10:42