Как я циклично выполняюсь только через каталоги в ударе?

Первое число является индексом задания; связанные с заданием команды (jobs, fg, и т.д.), используют их. Так, например, если Вы получаете вывод [2] 2847, Вы могли работать fg 2 к переднему плану то задание.

Насколько я мог сказать от просматривания источника, нет способа отключить сообщение. Одна проверка, которую это действительно делает, должна гарантировать, что оболочка является интерактивной, поэтому при выполнении команды в неинтерактивной оболочке, Вы не получите тот вывод. Например, Вы могли выполнить его в подоболочке:

$ (your_command &)

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

Если Вы готовы исправить bash, можно просто избавиться от который особый вывод. В ударе 4.2 это находится в jobs.c на строке 1428:

fprintf (stderr, "[%d] %ld\n", job + 1, (long)pid);

Это называют при других обстоятельствах; если Вы просто хотите, который уводят для этого конкретного случая, можно прокомментировать execute_cmd.c, строка 762:

DESCRIBE_PID (last_made_pid);
268
21.10.2013, 15:13
13 ответов

Если необходимо выбрать более определенные файлы, чем только использование каталогов find и передайте его while read:

shopt -s dotglob
find * -prune -type d | while IFS= read -r d; do 
    echo "$d"
done

Использовать shopt -u dotglob исключить скрытые каталоги (или setopt dotglob/unsetopt dotglob в zsh).

IFS= постараться не разделять имена файлов, содержащие один из $IFS, например: 'a b'

см. ответ AsymLabs ниже для больше find опции


править:
В случае, если необходимо создать стоимость выхода из цикла с условием продолжения, можно обойти дополнительную подоболочку этим приемом:

while IFS= read -r d; do 
    if [ "$d" == "something" ]; then exit 1; fi
done < <(find * -prune -type d)
22
27.01.2020, 19:26

Можно указать наклонную черту в конце для соответствия только каталогам:

for d in */ ; do
    echo "$d"
done
353
27.01.2020, 19:26

Можно протестировать с -d:

for f in *; do
    if [ -d "$f" ]; then
        # $f is a directory
    fi
done

Это - один из тестовых операторов файла.

82
27.01.2020, 19:26
  • 1
    Обратите внимание, что это будет включать символьные ссылки на каталоги. –  Stéphane Chazelas 14.08.2013, 19:12
  • 2
    if [[ -d "$f" && ! -L "$f" ]] исключит символьные ссылки –  rubo77 22.10.2013, 09:33

Можно использовать чистый удар для этого, но лучше использовать, найдите:

find . -maxdepth 1 -type d -exec echo {} \;

(найдите, дополнительно будет включать скрытые каталоги),

12
27.01.2020, 19:26
  • 1
    Обратите внимание, что это не включает символьные ссылки на каталоги. Можно использовать shopt -s dotglob для bash включать скрытые каталоги. Ваш будет также включать .. Также отметьте это -maxdepth не стандартная опция (-prune ). –  Stéphane Chazelas 14.08.2013, 19:11
  • 2
    dotglob опция интересна, но dotglob только относится к использованию *. find . будет всегда включать скрытые каталоги (и текущий dir также) ре –  rubo77 22.10.2013, 08:28

Это сделано для нахождения и видимых и скрытых каталогов в рамках существующего рабочего каталога, исключая корневой каталог:

только к циклу через каталоги:

 find -path './*' -prune -type d

включать символьные ссылки в результат:

find -L -path './*' -prune -type d

сделать что-то к каждому каталогу (исключая символьные ссылки):

find -path './*' -prune -type d -print0 | xargs -0 <cmds>

исключить скрытые каталоги:

find -path './[^.]*' -prune -type d

выполнить несколько команд на возвращаемом значения (очень изобретенный пример):

find -path './[^.]*' -prune -type d -print0 | xargs -0 -I '{}' sh -c \
"printf 'first: %-40s' '{}'; printf 'second: %s\n' '{}'"

вместо 'sh-c' может также использовать 'удар-c', и т.д.

6
27.01.2020, 19:26
  • 1
    , Что происходит, если эхо '* /' в 'для d в эхе * /' содержит, скажем, 60 000 каталогов? –  AsymLabs 21.10.2013, 07:05
  • 2
    Вы получите "Слишком много файлов" ошибка, но это может быть решено: Как обойти “Слишком много открытых файлов” в debian –  rubo77 21.10.2013, 07:09
  • 3
    xargs пример только был бы работы для подмножества имен каталогов 9e.g. те, которые имеют пробелы или новые строки, не работали бы). Лучше использовать ... -print0 | xargs -0 ... если Вы не знаете, каковы точные имена. –  Anthon 21.10.2013, 07:50
  • 4
    @rubo77, добавил способ исключить скрытые файлы/каталоги и выполнение нескольких команд - конечно, это может быть сделано со сценарием также. –  AsymLabs 21.10.2013, 14:22
  • 5
    я добавил пример в своем ответе внизу, как сделать что-то к каждому каталогу с помощью функции с find * | while read file; do ... –  rubo77 22.10.2013, 07:37

Можно циклично выполниться через все каталоги включая скрытые каталоги (начинающийся с точки) в одной строке и нескольких командах с:

for file in */ .*/ ; do echo "$file is a directory"; done

Если Вы хотите исключить символьные ссылки:

for file in *; do 
  if [[ -d "$file" && ! -L "$file" ]]; then
    echo "$file is a directory"; 
  fi; 
done

примечание: использование списка */ .*/ работы в ударе, но также и дисплеи папки . и .. в то время как в zsh это не покажет их, но бросит ошибку, если не будет никакого скрытого файла в папке

Более чистая версия, которая будет включать скрытые каталоги и исключать../, будет с dotglob опцией:

shopt -s dotglob
for file in */ ; do echo "$file is a directory"; done

(или setopt dotglob в zsh)

можно сбросить dotglob с

shopt -u dotglob
3
27.01.2020, 19:26

Использовать find с -exec циклично выполняться через каталоги и вызывать функцию в исполнительной опции:

dosomething () {
  echo "doing something with $1"
}
export -f dosomething
find -path './*' -prune -type d -exec bash -c 'dosomething "$0"' {} \;

Использовать shopt -s dotglob или shopt -u dotglob включать/исключать скрытые каталоги

0
27.01.2020, 19:26

Это будет включать полный путь в каждый каталог в списке:

for i in $(find $PWD -maxdepth 1 -type d); do echo $i; done
3
27.01.2020, 19:26
  • 1
    повреждается при использовании папок с –  Alejandro Sazo 24.10.2016, 05:15
ls -d */ | while read d
do
        echo $d
done
-1
27.01.2020, 19:26

Помните, что решение choroba, хотя и элегантно, может вызвать неожиданное поведение, если в текущем каталоге нет доступных каталогов. В этом состоянии вместо того, чтобы пропускать цикл for , bash выполнит цикл ровно один раз, где d равно * / :

#!/usr/bin/env bash

for d in */; do
    # Will print */ if no directories are available
    echo $d
done

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

#!/usr/bin/env bash

for f in *; do
    if [ -d ${f} ]; then
        # Will not run if no directories are available
        echo $f
    fi
done

Этот код будет перебирать все файлы в текущем каталоге, проверять, является ли f каталогом, затем echo f , если условие возвращает true . Если f равно * / , echo $ f не будет выполняться.

33
27.01.2020, 19:26
ls -l | grep ^d

или:

ll | grep ^d

Вы можете установить его как псевдоним

-6
27.01.2020, 19:26

Этот ответ предполагает, что все , что нужно сделать, это найти подкаталоги -некоторого верхнего -каталога уровня.

Ответ, относящийся кbash(и в некоторой степени zshоболочке ), см. во второй части вики-ответа rubo77 , где dotglobи nullglobиспользуется для правильного перебора каталогов (или символических ссылок на каталоги )в одном каталоге.

Для портативного решения, которое не зависит от bashдля фактического выбора файлов, вы можете использовать findдля циклического перебора всех каталогов в некотором каталоге верхнего -уровня:

topdir=.

find "$topdir" ! -path "$topdir" -prune -type d -exec sh -c '
    for dirpath do
        # user code goes here, using "$dirpath"
        printf "\"%s\" is a directory\n" "$dirpath"
    done' sh {} +

В приведенном выше коде предполагается, что интересующий нас верхний каталог — это текущий каталог(.). Установите topdirна какой-либо другой путь, чтобы использовать его в другом каталоге.

Утилите findпредлагается игнорировать пути, идентичные начальному пути поиска с ! -path "$topdir", а затем сократить (и не вводить )любые другие найденные пути. Это ограничивает поиск только каталогом, на который ссылается $topdir.

Пути, которые являются каталогами (-type d), собираются, и sh -cскрипт выполняется с их пакетами в качестве аргументов. Сценарий sh -c— это код, который мы хотели бы выполнить для всех каталогов, поэтому он выполняет итерацию по заданным аргументам и делает с каждым из них все, что нужно. Если вам нужно сделать что-то, что требует bash, вы, очевидно, вместо этого используете bash -c.

Сценарий sh -cможно было бы выделить в отдельный сценарий вот так:

#!/bin/sh

for dirpath do
    # user code goes here, using "$dirpath"
    printf '"%s" is a directory\n' "$dirpath"
done

... который будет вызываться из findвот так:

find "$topdir" ! -path "$topdir" -prune -type d -exec./myscript.sh {} +

См. также:

2
04.03.2021, 07:54

Список только каталогов. включительно с пробелами в именах включать скрытый каталог -Aпри необходимости:

grep '/$' <(ls -AF)

Возможные продолжения:

| xargs -I{} echo {}
| while read; do echo $REPLY; done

Но судя по каверзному вопросу имелся в виду вывод каталогов в цикле forи средствами шелла:

for i in */.[^.]*/; do
        [ -h "${i%?}" ] || echo $i
done
1
08.09.2021, 21:14

Теги

Похожие вопросы