Если вы доверяете get.docker.com, запустите:
curl -sSL https://get.docker.com/ | sudo bash
Сценарий ниже добавит список ко всем субдирерам из каталога рекурсивно:
#!/usr/bin/env python3
import os
import sys
for root, dirs, files in os.walk(sys.argv[1]):
for dr in dirs:
dr = os.path.join(root, dr)
open(os.path.join(dr, "list.txt"), "wt").write(
",".join(f for f in os.listdir(dr) if f != "list.txt")
)
python3 /path/to/dirlists.py /path/to/maindirectory
Как уже упоминалось, скрипт добавляет list.txt ко всем sub - [!d1 ]. Если вы также хотите или хотите иметь список в главном (корневом) -dir вашего каталога, укажите:
os.listdir(dr)
Запустите его с основным каталогом в качестве аргумента: python3 /path/to/dirlists.py /path/to/maindirectory
Как запрошено в комментарии:
Если вам нужна строка в list.txt, чтобы закончить запятую, просто замените: [!d23 ]
",".join(f for f in os.listdir(dr) if f != "list.txt")
by:
",".join(f for f in os.listdir(dr) if f != "list.txt")+","
Учесть отступ, поместить замену в том же положении
Сценарий ниже добавит список ко всем субдирерам из каталога рекурсивно:
#!/usr/bin/env python3
import os
import sys
for root, dirs, files in os.walk(sys.argv[1]):
for dr in dirs:
dr = os.path.join(root, dr)
open(os.path.join(dr, "list.txt"), "wt").write(
",".join(f for f in os.listdir(dr) if f != "list.txt")
)
python3 /path/to/dirlists.py /path/to/maindirectory
Как уже упоминалось, скрипт добавляет list.txt ко всем sub - . Если вы также хотите или хотите иметь список в главном (корневом) -dir вашего каталога, укажите:
os.listdir(dr)
Запустите его с основным каталогом в качестве аргумента: python3 /path/to/dirlists.py /path/to/maindirectory
Как запрошено в комментарии:
Если вам нужна строка в list.txt, чтобы закончить запятую, просто замените:
",".join(f for f in os.listdir(dr) if f != "list.txt")
by:
",".join(f for f in os.listdir(dr) if f != "list.txt")+","
Учесть отступ, поместить замену в том же положении
Сценарий ниже добавит список ко всем субдирерам из каталога рекурсивно:
#!/usr/bin/env python3
import os
import sys
for root, dirs, files in os.walk(sys.argv[1]):
for dr in dirs:
dr = os.path.join(root, dr)
open(os.path.join(dr, "list.txt"), "wt").write(
",".join(f for f in os.listdir(dr) if f != "list.txt")
)
python3 /path/to/dirlists.py /path/to/maindirectory
Как уже упоминалось, скрипт добавляет list.txt ко всем sub - . Если вы также хотите или хотите иметь список в главном (корневом) -dir вашего каталога, укажите:
os.listdir(dr)
Запустите его с основным каталогом в качестве аргумента: python3 /path/to/dirlists.py /path/to/maindirectory
Как запрошено в комментарии:
Если вам нужна строка в list.txt, чтобы закончить запятую, просто замените:
",".join(f for f in os.listdir(dr) if f != "list.txt")
by:
",".join(f for f in os.listdir(dr) if f != "list.txt")+","
Учесть отступ, поместить замену в том же положении
Сценарий ниже добавит список ко всем субдирерам из каталога рекурсивно:
#!/usr/bin/env python3
import os
import sys
for root, dirs, files in os.walk(sys.argv[1]):
for dr in dirs:
dr = os.path.join(root, dr)
open(os.path.join(dr, "list.txt"), "wt").write(
",".join(f for f in os.listdir(dr) if f != "list.txt")
)
python3 /path/to/dirlists.py /path/to/maindirectory
Как уже упоминалось, скрипт добавляет list.txt ко всем sub - . Если вы также хотите или хотите иметь список в главном (корневом) -dir вашего каталога, укажите:
os.listdir(dr)
Запустите его с основным каталогом в качестве аргумента: python3 /path/to/dirlists.py /path/to/maindirectory
Как запрошено в комментарии:
Если вам нужна строка в list.txt, чтобы закончить запятую, просто замените:
",".join(f for f in os.listdir(dr) if f != "list.txt")
by:
",".join(f for f in os.listdir(dr) if f != "list.txt")+","
Учесть отступ, поместить замену в том же положении
Сценарий ниже добавит список ко всем субдирерам из каталога рекурсивно:
#!/usr/bin/env python3
import os
import sys
for root, dirs, files in os.walk(sys.argv[1]):
for dr in dirs:
dr = os.path.join(root, dr)
open(os.path.join(dr, "list.txt"), "wt").write(
",".join(f for f in os.listdir(dr) if f != "list.txt")
)
python3 /path/to/dirlists.py /path/to/maindirectory
Как уже упоминалось, скрипт добавляет list.txt ко всем sub - . Если вы также хотите или хотите иметь список в главном (корневом) -dir вашего каталога, укажите:
os.listdir(dr)
Запустите его с основным каталогом в качестве аргумента: python3 /path/to/dirlists.py /path/to/maindirectory
Как запрошено в комментарии:
Если вам нужна строка в list.txt, чтобы закончить запятую, просто замените:
",".join(f for f in os.listdir(dr) if f != "list.txt")
by:
",".join(f for f in os.listdir(dr) if f != "list.txt")+","
Учесть отступ, поместить замену в том же положении
Чтобы сделать его рекурсивным, сначала включите globstar
shopt -s globstar
Затем в родительском каталоге (A в вашей структуре) вы можете запустить:
for d in **; do [[ -d "$d" ]] && (find "$d" -mindepth 1 -maxdepth 1 \( -not -name "list.txt" \) -printf '%f,' | sed 's/,$/\n/') |tee "$d"/list.txt ; done
или немного более читаемо
for d in **; do
[[ -d "$d" ]] &&
(find "$d" -mindepth 1 -maxdepth 1 \( -not -name "list.txt" \) -printf '%f,' | sed 's/,$/\n/') | tee "$d"/list.txt
done
, который, если каталог a содержит
├── a
│ ├── 1.txt
│ ├── 2.txt
│ ├── 3.txt
│ ├── a badly named file &
│ └── Z
, создаст список в каталоге a, который выглядит так: [ ! d4]
2.txt,1.txt,3.txt,Z,a badly named file &
find не производит упорядоченный вывод, поэтому, если это проблема, мне придется подумать о лучшем способе. [F12] в выражении find состоит в том, чтобы исключить включение самого списка, а выражение sed - только для удаления конечной запятой. Поражайте все эти дополнительные байты.
Когда вы закончите
shopt -u globstar
, вы можете отключить globstar Используйте find, чтобы сначала получить каталоги, затем оболочка выполнит для вас работу:
$ tree
.
├── a_directory
│ ├── a_file
│ ├── a_subdir
│ └── mv-files.py
└── another_dir
├── {file}1
└── {file}2
3 directories, 4 files
$ find -type d -exec bash -c 'cd $1; find -maxdepth 1 -not -name "." -not -name "list.txt" -printf "%f," | awk "{print substr(\$0,0,length(\$0)-1)}" > list.txt' bash "{}" \;
$ cat a_directory/list.txt
mv-files.py,a_file,list.txt,a_subdir
Как это работает:
мы используем команду find с -type d, чтобы отфильтровать все инструкции каталогов -exec с помощью \; terminator, чтобы мы могли запускать указанную команду для каждого аргумента, который find получает в -exec, который мы запускаем bash с флагом -c, с которым мы передаем аргумент $0 аргумента bash и $1, являющийся каталогом, который outter find locaed bash будет вводить данный каталог и использовать find с аргументом - maxdepth 1 чтобы ограничить эту команду только этим подкаталогом. -not -name "." исключает ссылку каталога ., которая ссылается на self. Затем мы передаем текст в awk, который служит только для удаления последнего ,, указанного find, так что у нас есть действительный список CSV. Обратите внимание на использование двойных кавычек и \$. Это предназначено для упрощения цитирования и предотвращения интерпретации bash $0 как своих собственных позиционных аргументов, а скорее как команды awk. Весь список элементов, которые получает внутренний find, будет отправлен на list.txt через перенаправление >.Дополнительным усовершенствованием этого может быть использование -not -name "list.txt" внутри внутренней команды find для исключения самого файла списка (потому что из-за >, всегда создающего файл для записи первым, list.txt также будет появятся в списке).
Лично, если бы я делал это для себя, я бы написал список файлов с разделителем \0, чтобы избежать трудностей с именами файлов, но это также требует запоминания того, что [ f36] находится в формате \0 и записывает для него функцию парсера.
Для удобства чтения здесь представлена полная версия скрипта вместо однострочного.
Сценарий:
#!/bin/bash
# note : this assumes you run the script from top-most directory
find -type d | while IFS= read -r directory;
do
cd "$directory"
find -maxdepth 1 -not -name "." -not -name "list.txt" -printf "%f," |
awk "{print substr(\$0,0,length(\$0)-1)}" > list.txt
cd - > /dev/null
done
Обратите внимание, что этот скрипт запускается из самого верхнего каталога. Он также включает «я» в список, если он хранится в том же каталоге. Если вы поместите его на ~/bin, например (или любой другой каталог, принадлежащий переменной $PATH), и запустите его, имя сценария не появится в списке.
Тест:
$ tree
.
├── a_directory
│ ├── a_file
│ ├── a_subdir
│ └── mv-files.py
├── another_dir
│ ├── {file}1
│ └── {file}2
└── make_lists.sh
3 directories, 5 files
$ ./make_lists.sh
$ tree
.
├── a_directory
│ ├── a_file
│ ├── a_subdir
│ │ └── list.txt
│ ├── list.txt
│ └── mv-files.py
├── another_dir
│ ├── {file}1
│ ├── {file}2
│ └── list.txt
├── list.txt
└── make_lists.sh
3 directories, 9 files
$ cat a_directory/list.txt
mv-files.py,a_file,a_subdir
Используйте find, чтобы сначала получить каталоги, затем оболочка выполнит для вас работу:
$ tree
.
├── a_directory
│ ├── a_file
│ ├── a_subdir
│ └── mv-files.py
└── another_dir
├── {file}1
└── {file}2
3 directories, 4 files
$ find -type d -exec bash -c 'cd $1; find -maxdepth 1 -not -name "." -not -name "list.txt" -printf "%f," | awk "{print substr(\$0,0,length(\$0)-1)}" > list.txt' bash "{}" \;
$ cat a_directory/list.txt
mv-files.py,a_file,list.txt,a_subdir
Как это работает:
мы используем команду find с -type d, чтобы отфильтровать все инструкции каталогов -exec с помощью \; terminator, чтобы мы могли запускать указанную команду для каждого аргумента, который find получает в -exec, который мы запускаем bash с флагом -c, с которым мы передаем аргумент $0 аргумента bash и $1, являющийся каталогом, который outter find locaed bash будет вводить данный каталог и использовать find с аргументом - maxdepth 1 чтобы ограничить эту команду только этим подкаталогом. -not -name "." исключает ссылку каталога ., которая ссылается на self. Затем мы передаем текст в awk, который служит только для удаления последнего ,, указанного find, так что у нас есть действительный список CSV. Обратите внимание на использование двойных кавычек и \$. Это предназначено для упрощения цитирования и предотвращения интерпретации bash $0 как своих собственных позиционных аргументов, а скорее как команды awk. Весь список элементов, которые получает внутренний find, будет отправлен на list.txt через перенаправление >.Дополнительным усовершенствованием этого может быть использование -not -name "list.txt" внутри внутренней команды find для исключения самого файла списка (потому что из-за >, всегда создающего файл для записи первым, list.txt также будет появятся в списке).
Лично, если бы я делал это для себя, я бы написал список файлов с разделителем \0, чтобы избежать трудностей с именами файлов, но это также требует запоминания того, что list.txt находится в формате \0 и записывает для него функцию парсера.
Для удобства чтения здесь представлена полная версия скрипта вместо однострочного.
Сценарий:
#!/bin/bash
# note : this assumes you run the script from top-most directory
find -type d | while IFS= read -r directory;
do
cd "$directory"
find -maxdepth 1 -not -name "." -not -name "list.txt" -printf "%f," |
awk "{print substr(\$0,0,length(\$0)-1)}" > list.txt
cd - > /dev/null
done
Обратите внимание, что этот скрипт запускается из самого верхнего каталога. Он также включает «я» в список, если он хранится в том же каталоге. Если вы поместите его на ~/bin, например (или любой другой каталог, принадлежащий переменной $PATH), и запустите его, имя сценария не появится в списке.
Тест:
$ tree
.
├── a_directory
│ ├── a_file
│ ├── a_subdir
│ └── mv-files.py
├── another_dir
│ ├── {file}1
│ └── {file}2
└── make_lists.sh
3 directories, 5 files
$ ./make_lists.sh
$ tree
.
├── a_directory
│ ├── a_file
│ ├── a_subdir
│ │ └── list.txt
│ ├── list.txt
│ └── mv-files.py
├── another_dir
│ ├── {file}1
│ ├── {file}2
│ └── list.txt
├── list.txt
└── make_lists.sh
3 directories, 9 files
$ cat a_directory/list.txt
mv-files.py,a_file,a_subdir
Чтобы сделать его рекурсивным, сначала включите globstar
shopt -s globstar
Затем в родительском каталоге (A в вашей структуре) вы можете запустить:
for d in **; do [[ -d "$d" ]] && (find "$d" -mindepth 1 -maxdepth 1 \( -not -name "list.txt" \) -printf '%f,' | sed 's/,$/\n/') |tee "$d"/list.txt ; done
или немного более читаемо
for d in **; do
[[ -d "$d" ]] &&
(find "$d" -mindepth 1 -maxdepth 1 \( -not -name "list.txt" \) -printf '%f,' | sed 's/,$/\n/') | tee "$d"/list.txt
done
, который, если каталог a содержит
├── a
│ ├── 1.txt
│ ├── 2.txt
│ ├── 3.txt
│ ├── a badly named file &
│ └── Z
, создаст список в каталоге a, который выглядит так: [ ! d4] 2.txt,1.txt,3.txt,Z,a badly named file &
find не производит упорядоченный вывод, поэтому, если это проблема, мне придется подумать о лучшем способе. [F12] в выражении find состоит в том, чтобы исключить включение самого списка, а выражение sed - только для удаления конечной запятой. Поражайте все эти дополнительные байты.
Когда вы закончите
shopt -u globstar
, вы можете отключить globstar Используйте find, чтобы сначала получить каталоги, затем оболочка выполнит для вас работу:
$ tree
.
├── a_directory
│ ├── a_file
│ ├── a_subdir
│ └── mv-files.py
└── another_dir
├── {file}1
└── {file}2
3 directories, 4 files
$ find -type d -exec bash -c 'cd $1; find -maxdepth 1 -not -name "." -not -name "list.txt" -printf "%f," | awk "{print substr(\$0,0,length(\$0)-1)}" > list.txt' bash "{}" \;
$ cat a_directory/list.txt
mv-files.py,a_file,list.txt,a_subdir
Как это работает:
мы используем команду find с -type d, чтобы отфильтровать все инструкции каталогов -exec с помощью \; terminator, чтобы мы могли запускать указанную команду для каждого аргумента, который find получает в -exec, который мы запускаем bash с флагом -c, с которым мы передаем аргумент $0 аргумента bash и $1, являющийся каталогом, который outter find locaed bash будет вводить данный каталог и использовать find с аргументом - maxdepth 1 чтобы ограничить эту команду только этим подкаталогом. -not -name "." исключает ссылку каталога ., которая ссылается на self. Затем мы передаем текст в awk, который служит только для удаления последнего ,, указанного find, так что у нас есть действительный список CSV. Обратите внимание на использование двойных кавычек и \$. Это предназначено для упрощения цитирования и предотвращения интерпретации bash $0 как своих собственных позиционных аргументов, а скорее как команды awk. Весь список элементов, которые получает внутренний find, будет отправлен на list.txt через перенаправление >.Дополнительным усовершенствованием этого может быть использование -not -name "list.txt" внутри внутренней команды find для исключения самого файла списка (потому что из-за >, всегда создающего файл для записи первым, list.txt также будет появятся в списке).
Лично, если бы я делал это для себя, я бы написал список файлов с разделителем \0, чтобы избежать трудностей с именами файлов, но это также требует запоминания того, что list.txt находится в формате \0 и записывает для него функцию парсера.
Для удобства чтения здесь представлена полная версия скрипта вместо однострочного.
Сценарий:
#!/bin/bash
# note : this assumes you run the script from top-most directory
find -type d | while IFS= read -r directory;
do
cd "$directory"
find -maxdepth 1 -not -name "." -not -name "list.txt" -printf "%f," |
awk "{print substr(\$0,0,length(\$0)-1)}" > list.txt
cd - > /dev/null
done
Обратите внимание, что этот скрипт запускается из самого верхнего каталога. Он также включает «я» в список, если он хранится в том же каталоге. Если вы поместите его на ~/bin, например (или любой другой каталог, принадлежащий переменной $PATH), и запустите его, имя сценария не появится в списке.
Тест:
$ tree
.
├── a_directory
│ ├── a_file
│ ├── a_subdir
│ └── mv-files.py
├── another_dir
│ ├── {file}1
│ └── {file}2
└── make_lists.sh
3 directories, 5 files
$ ./make_lists.sh
$ tree
.
├── a_directory
│ ├── a_file
│ ├── a_subdir
│ │ └── list.txt
│ ├── list.txt
│ └── mv-files.py
├── another_dir
│ ├── {file}1
│ ├── {file}2
│ └── list.txt
├── list.txt
└── make_lists.sh
3 directories, 9 files
$ cat a_directory/list.txt
mv-files.py,a_file,a_subdir
Чтобы сделать его рекурсивным, сначала включите globstar
shopt -s globstar
Затем в родительском каталоге (A в вашей структуре) вы можете запустить:
for d in **; do [[ -d "$d" ]] && (find "$d" -mindepth 1 -maxdepth 1 \( -not -name "list.txt" \) -printf '%f,' | sed 's/,$/\n/') |tee "$d"/list.txt ; done
или немного более читаемо
for d in **; do
[[ -d "$d" ]] &&
(find "$d" -mindepth 1 -maxdepth 1 \( -not -name "list.txt" \) -printf '%f,' | sed 's/,$/\n/') | tee "$d"/list.txt
done
, который, если каталог a содержит
├── a
│ ├── 1.txt
│ ├── 2.txt
│ ├── 3.txt
│ ├── a badly named file &
│ └── Z
, создаст список в каталоге a, который выглядит так: [ ! d4] 2.txt,1.txt,3.txt,Z,a badly named file &
find не производит упорядоченный вывод, поэтому, если это проблема, мне придется подумать о лучшем способе. [F12] в выражении find состоит в том, чтобы исключить включение самого списка, а выражение sed - только для удаления конечной запятой. Поражайте все эти дополнительные байты.
Когда вы закончите
shopt -u globstar
, вы можете отключить globstar Используйте find, чтобы сначала получить каталоги, затем оболочка выполнит для вас работу:
$ tree
.
├── a_directory
│ ├── a_file
│ ├── a_subdir
│ └── mv-files.py
└── another_dir
├── {file}1
└── {file}2
3 directories, 4 files
$ find -type d -exec bash -c 'cd $1; find -maxdepth 1 -not -name "." -not -name "list.txt" -printf "%f," | awk "{print substr(\$0,0,length(\$0)-1)}" > list.txt' bash "{}" \;
$ cat a_directory/list.txt
mv-files.py,a_file,list.txt,a_subdir
Как это работает:
мы используем команду find с -type d, чтобы отфильтровать все инструкции каталогов -exec с помощью \; terminator, чтобы мы могли запускать указанную команду для каждого аргумента, который find получает в -exec, который мы запускаем bash с флагом -c, с которым мы передаем аргумент $0 аргумента bash и $1, являющийся каталогом, который outter find locaed bash будет вводить данный каталог и использовать find с аргументом - maxdepth 1 чтобы ограничить эту команду только этим подкаталогом. -not -name "." исключает ссылку каталога ., которая ссылается на self. Затем мы передаем текст в awk, который служит только для удаления последнего ,, указанного find, так что у нас есть действительный список CSV. Обратите внимание на использование двойных кавычек и \$. Это предназначено для упрощения цитирования и предотвращения интерпретации bash $0 как своих собственных позиционных аргументов, а скорее как команды awk. Весь список элементов, которые получает внутренний find, будет отправлен на list.txt через перенаправление >.Дополнительным усовершенствованием этого может быть использование -not -name "list.txt" внутри внутренней команды find для исключения самого файла списка (потому что из-за >, всегда создающего файл для записи первым, list.txt также будет появятся в списке).
Лично, если бы я делал это для себя, я бы написал список файлов с разделителем \0, чтобы избежать трудностей с именами файлов, но это также требует запоминания того, что list.txt находится в формате \0 и записывает для него функцию парсера.
Для удобства чтения здесь представлена полная версия скрипта вместо однострочного.
Сценарий:
#!/bin/bash
# note : this assumes you run the script from top-most directory
find -type d | while IFS= read -r directory;
do
cd "$directory"
find -maxdepth 1 -not -name "." -not -name "list.txt" -printf "%f," |
awk "{print substr(\$0,0,length(\$0)-1)}" > list.txt
cd - > /dev/null
done
Обратите внимание, что этот скрипт запускается из самого верхнего каталога. Он также включает «я» в список, если он хранится в том же каталоге. Если вы поместите его на ~/bin, например (или любой другой каталог, принадлежащий переменной $PATH), и запустите его, имя сценария не появится в списке.
Тест:
$ tree
.
├── a_directory
│ ├── a_file
│ ├── a_subdir
│ └── mv-files.py
├── another_dir
│ ├── {file}1
│ └── {file}2
└── make_lists.sh
3 directories, 5 files
$ ./make_lists.sh
$ tree
.
├── a_directory
│ ├── a_file
│ ├── a_subdir
│ │ └── list.txt
│ ├── list.txt
│ └── mv-files.py
├── another_dir
│ ├── {file}1
│ ├── {file}2
│ └── list.txt
├── list.txt
└── make_lists.sh
3 directories, 9 files
$ cat a_directory/list.txt
mv-files.py,a_file,a_subdir
Чтобы сделать его рекурсивным, сначала включите globstar
shopt -s globstar
Затем в родительском каталоге (A в вашей структуре) вы можете запустить:
for d in **; do [[ -d "$d" ]] && (find "$d" -mindepth 1 -maxdepth 1 \( -not -name "list.txt" \) -printf '%f,' | sed 's/,$/\n/') |tee "$d"/list.txt ; done
или немного более читаемо
for d in **; do
[[ -d "$d" ]] &&
(find "$d" -mindepth 1 -maxdepth 1 \( -not -name "list.txt" \) -printf '%f,' | sed 's/,$/\n/') | tee "$d"/list.txt
done
, который, если каталог a содержит
├── a
│ ├── 1.txt
│ ├── 2.txt
│ ├── 3.txt
│ ├── a badly named file &
│ └── Z
, создаст список в каталоге a, который выглядит так: [ ! d4] 2.txt,1.txt,3.txt,Z,a badly named file &
find не производит упорядоченный вывод, поэтому, если это проблема, мне придется подумать о лучшем способе. [F12] в выражении find состоит в том, чтобы исключить включение самого списка, а выражение sed - только для удаления конечной запятой. Поражайте все эти дополнительные байты.
Когда вы закончите
shopt -u globstar
, вы можете отключить globstar Используйте find, чтобы сначала получить каталоги, затем оболочка выполнит для вас работу:
$ tree
.
├── a_directory
│ ├── a_file
│ ├── a_subdir
│ └── mv-files.py
└── another_dir
├── {file}1
└── {file}2
3 directories, 4 files
$ find -type d -exec bash -c 'cd $1; find -maxdepth 1 -not -name "." -not -name "list.txt" -printf "%f," | awk "{print substr(\$0,0,length(\$0)-1)}" > list.txt' bash "{}" \;
$ cat a_directory/list.txt
mv-files.py,a_file,list.txt,a_subdir
Как это работает:
мы используем команду find с -type d, чтобы отфильтровать все инструкции каталогов -exec с помощью \; terminator, чтобы мы могли запускать указанную команду для каждого аргумента, который find получает в -exec, который мы запускаем bash с флагом -c, с которым мы передаем аргумент $0 аргумента bash и $1, являющийся каталогом, который outter find locaed bash будет вводить данный каталог и использовать find с аргументом - maxdepth 1 чтобы ограничить эту команду только этим подкаталогом. -not -name "." исключает ссылку каталога ., которая ссылается на self. Затем мы передаем текст в awk, который служит только для удаления последнего ,, указанного find, так что у нас есть действительный список CSV. Обратите внимание на использование двойных кавычек и \$. Это предназначено для упрощения цитирования и предотвращения интерпретации bash $0 как своих собственных позиционных аргументов, а скорее как команды awk. Весь список элементов, которые получает внутренний find, будет отправлен на list.txt через перенаправление >.Дополнительным усовершенствованием этого может быть использование -not -name "list.txt" внутри внутренней команды find для исключения самого файла списка (потому что из-за >, всегда создающего файл для записи первым, list.txt также будет появятся в списке).
Лично, если бы я делал это для себя, я бы написал список файлов с разделителем \0, чтобы избежать трудностей с именами файлов, но это также требует запоминания того, что list.txt находится в формате \0 и записывает для него функцию парсера.
Для удобства чтения здесь представлена полная версия скрипта вместо однострочного.
Сценарий:
#!/bin/bash
# note : this assumes you run the script from top-most directory
find -type d | while IFS= read -r directory;
do
cd "$directory"
find -maxdepth 1 -not -name "." -not -name "list.txt" -printf "%f," |
awk "{print substr(\$0,0,length(\$0)-1)}" > list.txt
cd - > /dev/null
done
Обратите внимание, что этот скрипт запускается из самого верхнего каталога. Он также включает «я» в список, если он хранится в том же каталоге. Если вы поместите его на ~/bin, например (или любой другой каталог, принадлежащий переменной $PATH), и запустите его, имя сценария не появится в списке.
Тест:
$ tree
.
├── a_directory
│ ├── a_file
│ ├── a_subdir
│ └── mv-files.py
├── another_dir
│ ├── {file}1
│ └── {file}2
└── make_lists.sh
3 directories, 5 files
$ ./make_lists.sh
$ tree
.
├── a_directory
│ ├── a_file
│ ├── a_subdir
│ │ └── list.txt
│ ├── list.txt
│ └── mv-files.py
├── another_dir
│ ├── {file}1
│ ├── {file}2
│ └── list.txt
├── list.txt
└── make_lists.sh
3 directories, 9 files
$ cat a_directory/list.txt
mv-files.py,a_file,a_subdir
Чтобы сделать его рекурсивным, сначала включите globstar
shopt -s globstar
Затем в родительском каталоге (A в вашей структуре) вы можете запустить:
for d in **; do [[ -d "$d" ]] && (find "$d" -mindepth 1 -maxdepth 1 \( -not -name "list.txt" \) -printf '%f,' | sed 's/,$/\n/') |tee "$d"/list.txt ; done
или немного более читаемо
for d in **; do
[[ -d "$d" ]] &&
(find "$d" -mindepth 1 -maxdepth 1 \( -not -name "list.txt" \) -printf '%f,' | sed 's/,$/\n/') | tee "$d"/list.txt
done
, который, если каталог a содержит
├── a
│ ├── 1.txt
│ ├── 2.txt
│ ├── 3.txt
│ ├── a badly named file &
│ └── Z
, создаст список в каталоге a, который выглядит так: [ ! d4] 2.txt,1.txt,3.txt,Z,a badly named file &
find не производит упорядоченный вывод, поэтому, если это проблема, мне придется подумать о лучшем способе. [F12] в выражении find состоит в том, чтобы исключить включение самого списка, а выражение sed - только для удаления конечной запятой. Поражайте все эти дополнительные байты.
Когда вы закончите
shopt -u globstar
, вы можете отключить globstar