У меня есть список каталогов в текстовом файле, каждый может рассказать мне, как перечислять файлы только внутри каталогов, которые находятся в текстовом файле
Я точно не знаю сценарий, но объединение одного из них внутри цикла for в скрипте будет делать то, что вы хотите сделать.
Чтобы перечислить files only inside a directory, вы можете сделать один из них
$ ls -p | grep -v /
OR
$ ls -al | grep '^-'
$ find . -maxdepth 1 -type f
Вы можете использовать [F4] и [F5] Command Substitution для этого:
find $(</path/to/path_file) -type f
Это просто перечисляет все f ile, содержащиеся в каждом каталоге, упомянутом в /path/to/path_file. Конечно, вы можете настроить выход find дальше, например. добавив параметр -ls.
$ tree
.
├── path_file
├── test1
│ ├── 1
│ └── 2
└── test2
├── 3
└── 4
$ cat path_file
/path/to/test1
/path/to/test2
$ find $(</path/to/path_file) -type f
/path/to/test1/2
/path/to/test1/1
/path/to/test2/4
/path/to/test2/3
Здесь я использую абсолютные пути, поэтому не имеет значения, в какой директории find вызывается. Если path_file содержит относительные пути, вам нужно вызвать его в правильном каталоге - представьте, что каждый /path/to заменен на . в приведенном выше примере.
Если ваши пути содержат пробелы, вы можете установить bash Замена команды в новую строку с IFS=$'\n' перед вызовом find, таким образом, только линия новой линии будет рассматриваться как граница между путями.
Если вы хотите перейти по каждой строке, я настоятельно рекомендую parallel, чтобы остаться с find:
parallel find {} -type f :::: /path/to/path_file
parallel обрабатывает пробелы в аргументах правильно по дизайну.
Здесь есть две проблемы: один очень простой - перечисление файлов в каталогах, а другое, что может быть немного более неприятным - чтение файла по строкам и передача строк из этого файла в качестве аргументов.
Классический способ сделать это через петлю while IFS= read -r, и мы можем добавить к нему другие вещи
while IFS= read -r line || [ -n "$line" ] ;
do
[ "x$line" = "x" ] && continue
[ -d "./$line" ] && ls "./$line"
done < ./dirs.txt
Происходит несколько вещей:
IFS= read -r line часть будет читать строку без выполнения разбиения слов; это означает, что если у вас есть <space><space>directory_name, он будет читаться точно так же, как только directory_name. ./ рядом с проверками того, существует ли указанная директория в первую очередь, и ls - это защита от имен файлов, которые могут начинаться с -. Имена файлов, такие как -directory, могут быть неверно истолкованы командами как флаг -d с соответствующим значением irectory для этого флага; конечно, это приведет к ошибке, если такой флаг не существует для команды. [ "x$line" = "x" ] && continue будет проверять пустую переменную / пустую строку. Если переменная пуста, ls выводит содержимое для ./, что является неправильным поведением.Рекурсивный случай того же самого события может быть либо через find, либо в виде десертов, либо через globstar:
shopt -s globstar
while IFS= read -r line || [ -n "$line" ] ; do
[ "x$line" = "x" ] && continue
[ -d "$line" ] &&
for i in "$line"/** ; do
ls "$i"
done
done < "/path/to/dirs.txt"
Это простой пример, чтобы сделать это из командной строки:
ls `cat ./dirs.txt`
Заменить «dirs.txt» с именем файла, содержащего список ваших каталогов. Файл dirs.txt должен находиться в текущем рабочем каталоге, если вы не указали путь к dirs.txt. Чтобы перечислить файлы по одному экрану за раз:
ls `cat ./dirs.txt` | more
Это будет более сложно. Как Сергей Колодяжный отметил в комментариях, это будет работать неправильно, если ваш dirs.txt содержит каталог, в котором есть пробел или вкладки.
Я точно не знаю сценарий, но объединение одного из них внутри цикла for в скрипте будет делать то, что вы хотите сделать.
Чтобы перечислить files only inside a directory, вы можете сделать один из них
$ ls -p | grep -v /
OR
$ ls -al | grep '^-'
$ find . -maxdepth 1 -type f
Вы можете использовать [F4] и [F5] Command Substitution для этого:
find $(</path/to/path_file) -type f
Это просто перечисляет все f ile, содержащиеся в каждом каталоге, упомянутом в /path/to/path_file. Конечно, вы можете настроить выход find дальше, например. добавив параметр -ls.
$ tree
.
├── path_file
├── test1
│ ├── 1
│ └── 2
└── test2
├── 3
└── 4
$ cat path_file
/path/to/test1
/path/to/test2
$ find $(</path/to/path_file) -type f
/path/to/test1/2
/path/to/test1/1
/path/to/test2/4
/path/to/test2/3
Здесь я использую абсолютные пути, поэтому не имеет значения, в какой директории find вызывается. Если path_file содержит относительные пути, вам нужно вызвать его в правильном каталоге - представьте, что каждый /path/to заменен на . в приведенном выше примере.
Если ваши пути содержат пробелы, вы можете установить bash Замена команды в новую строку с IFS=$'\n' перед вызовом find, таким образом, только линия новой линии будет рассматриваться как граница между путями.
Если вы хотите перейти по каждой строке, я настоятельно рекомендую parallel, чтобы остаться с find:
parallel find {} -type f :::: /path/to/path_file
parallel обрабатывает пробелы в аргументах правильно по дизайну.
Здесь есть две проблемы: один очень простой - перечисление файлов в каталогах, а другое, что может быть немного более неприятным - чтение файла по строкам и передача строк из этого файла в качестве аргументов.
Классический способ сделать это через петлю while IFS= read -r, и мы можем добавить к нему другие вещи
while IFS= read -r line || [ -n "$line" ] ;
do
[ "x$line" = "x" ] && continue
[ -d "./$line" ] && ls "./$line"
done < ./dirs.txt
Происходит несколько вещей:
IFS= read -r line часть будет читать строку без выполнения разбиения слов; это означает, что если у вас есть <space><space>directory_name, он будет читаться точно так же, как только directory_name. ./ рядом с проверками того, существует ли указанная директория в первую очередь, и ls - это защита от имен файлов, которые могут начинаться с -. Имена файлов, такие как -directory, могут быть неверно истолкованы командами как флаг -d с соответствующим значением irectory для этого флага; конечно, это приведет к ошибке, если такой флаг не существует для команды. [ "x$line" = "x" ] && continue будет проверять пустую переменную / пустую строку. Если переменная пуста, ls выводит содержимое для ./, что является неправильным поведением.Рекурсивный случай того же самого события может быть либо через find, либо в виде десертов, либо через globstar:
shopt -s globstar
while IFS= read -r line || [ -n "$line" ] ; do
[ "x$line" = "x" ] && continue
[ -d "$line" ] &&
for i in "$line"/** ; do
ls "$i"
done
done < "/path/to/dirs.txt"
Это простой пример, чтобы сделать это из командной строки:
ls `cat ./dirs.txt`
Заменить «dirs.txt» с именем файла, содержащего список ваших каталогов. Файл dirs.txt должен находиться в текущем рабочем каталоге, если вы не указали путь к dirs.txt. Чтобы перечислить файлы по одному экрану за раз:
ls `cat ./dirs.txt` | more
Это будет более сложно. Как Сергей Колодяжный отметил в комментариях, это будет работать неправильно, если ваш dirs.txt содержит каталог, в котором есть пробел или вкладки.