Вопрос shell для печати даты изменения всех совпадений имен каталогов


Я хочу написать программу оболочки, которая будет проходить через все папки, имена которых соответствуют шаблону:

sudo sh  shell.sh   pub 

При запуске сценарий будет искать все папки, чье имя содержит pub и распечатать дату его изменения. Я хочу иметь код, который будет печатать результаты, как на этом изображении: enter image description here У меня есть этот код, но он не дает мне ожидаемого результата.

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

Я должен пройти через каждую папку и выводить текст echo 'the file '$1' was modified at '; и напечатать дату, как на изображении.

Я бы хотел получить такой результат:

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 

4
2018-06-07 07:18


происхождения




ответы:


Вы можете использовать find чтобы напечатать все это:

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

for pattern; do ... done петли по всем аргументам, с pattern переменная, заданная каждому аргументу по очереди.

С find, %P а также %t укажите путь к файлу и время модификации в -printf,


6
2018-06-07 07:42



+1 - %Tb %Td %TH:%TM (например. May 15 01:19) вместо %t дает такой формат, как запрошенный OP. - dessert


Вы можете использовать bash с globstar опция включена, как в следующем скрипте:

#!/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

Сохраните его как script, сделать его исполняемым с chmod +x script и назовите его так, как вы этого хотели:

bash /path/to/script testRegex Pub

Обратите внимание, что это будет искать, например, Pub*, если вы действительно хотите совместить *Pub*, изменение **/"$i"*/ в **/*"$i"*/, Если вы хотите сократить временную метку, попробуйте добавить | sed 's/:[^:]*$//' до конца do stat линия. Вы также должны попробовать %N вместо %n, особенно когда речь идет о именах каталогов с пробелами, этот формат является предпочтительным.

Если вы хотите более мелкомасштабный контроль формата даты, который вы можете использовать date, замените do stat выполните следующие действия:

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

Затем вы можете использовать обычный date последовательности в формате, man date, этот здесь печатает, например, May 15 01:19 как вы просили.

И последнее, но не менее важное: для корректной печати вывода любого из приведенных выше вы можете вставить вкладку после имени каталога и использовать column следующим образом:

#!/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'

Пример выполнения

$ 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

5
2018-06-07 08:06





find команда может делать то, что вам нужно, с одной строкой

Вы можете взглянуть на printf действия в find
Видетьman find для параметров деталей printf

пример

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


Чтобы получить больше информации
Официальный сайт для GNU find
25 Практические примеры команды find


4
2018-06-07 07:45





Вот небольшая вариация, которая использует -regex вместо -names:

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

Это может быть либо однострочный скрипт, либо еще лучше - функция. Назовите это так:

./finder.sh 'Vid\|Doc'

Это приводит к более идиоматическому, grepподобный подход.


2
2018-06-07 08:42