торкніться всіх папок у каталозі


14

Я намагаюся оновити часові позначки всіх папок у cwd, використовуючи це:

for file in `ls`; do touch $file; done

Але це, здається, не працює. Будь-які ідеї чому?

Відповіді:


21

Усі відповіді на даний момент (як і ваш приклад у запитанні) передбачають, що ви хочете до touchвсього в каталозі, навіть якщо ви сказали "торкніться всіх папок". Якщо виявиться, що каталог містить файли та папки, і ви хочете лише оновити папки, ви можете використовувати find:

$ find . -maxdepth 1 -mindepth 1 -type d -exec touch {} +

Або якщо ваша findреалізація не підтримує нестандартні -mindepth/ -maxdepthпредикати:

$ find . ! -name . -prune -type d -exec touch {} +

Це:

$ touch -c -- */

Має працювати в більшості снарядів, крім цього:

  • воно також буде touch посиланням на каталоги на додаток до звичайних каталогів
  • вона опустить приховані
  • якщо немає ніякого каталогу або символьного посилання на каталог, це створить файл з ім'ям , *відмінними від снарядів csh, tcsh, zsh, fishабо Thompson оболонка (яка буде повідомляти про помилку , а). Тут ми використовуємо цю -cпроблему, хоча це все ще може touchназиватися файлом без каталогу *.

З zsh, touchлише до каталогів, включаючи приховані:

touch -- *(D/)

Про що йдеться "{} \ +"?
javamonkey79

3
{} \+Спеціальний findсинтаксис - прочитати сторінку людини більше. Я думаю, що так touch -c ./*/би спрацювало.
jw013

2
Ви повинні включити -maxdepth 1до команди, щоб findвона не повторювалася в підпапки. ОП, схоже, хоче торкнутися лише тих папок у cwd, а не підпапок.
Стівен у понеділок

1
@ jw013 Було б - ти продовжуєш прив’язувати добрі ідеї до відповідей інших людей :)
Michael Mrozek

Чому б уникнути символу +? Чи є снаряди, які інтерпретують це?
Вітіко

11

Спробуйте

touch ./*

Це дозволяє уникнути зайвого forциклу, який породив би новий процес для кожного окремого файлу та працює для всіх імен файлів, навіть тих, що мають пробіли або тих, які виглядають як варіанти (як -t). Єдиний раз, коли б це не спрацювало, це якщо у вас в каталозі немає (не крапкових) файлів, і в такому випадку ви створили б файл з назвою *. Щоб уникнути цього, для конкретного випадку touchбільшості реалізацій є -cможливість (також її називають --no-createу версіях GNU) не створювати неіснуючі файли, тобто

touch -c ./*

Дивіться також посилання хороші в відповідь jasonwryan в так само як це одне .


1
Що буде, якщо у вас є 1 мільйон папок у cwd?
Стівен у понеділок

Якщо у вас трапляються проблеми "списку аргументів занадто довго", можливо, найкраще перейти на "важчі" інструменти, як-от відповідьfind . -type d -maxdepth1 -print0 | xargs -0 touch МайклаМрозека вище.
jw013

7

Не слід намагатися проаналізувати вихідls .

Крім того, ви повинні вказати свій, "$file"щоб захопити будь-який пробіл. Див. Http://www.grymoire.com/Unix/Quote.html

Щось подібне може досягти того, за чим ви йдете:

for file in *; do touch "$file"; done

Дивіться перші два підводні камені Баша для більш ретельного пояснення.


2
Близький, але не зовсім. A touch ./*повинен працювати в більшості випадків. Справді немає необхідності в forциклі, оскільки він touchможе приймати кілька файлів, і вам потрібно ./обробляти файли з такими іменами, як --helpправильно. Це хороший ресурс з цього питання.
jw013

Чому "*" працює?
javamonkey79

@ Javamonkey79 Це оболонка універсалізації .
jw013

1
@ jw013 Відмінний момент: і дякую за посилання на колеса.
jasonwryan

Зауважте, що *не зберігаються файли та каталоги, ім'я яких починається з крапки. Один із способів виправити це - включити параметр dotglobоболонки через shopt -s dotglob.
Вітіко

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.