Bash: создание имен файлов в соответствии с именами каталогов

Bash: создание имен файлов в соответствии с именами каталогов

Допустим, у меня есть структура каталогов, похожая наParent_dir/<name>/<date>/

Как можно использовать скрипт bash, помещенный в , Parent_dirдля навигации по каждому /<name>/<date>/подкаталогу и создания пустого текстового файла с именем <name>_<date>.txtвнутри /<name>/<date>/подкаталога?

решение1

Из Parent_dir:

for d in */*/; do f=${d/\//_}; touch -- "$d"/"${f::-1}.txt"; done

Обратите внимание, что это touchизменит временную метку любого существующего файла.

Для начала можно выполнить пробный запуск, заменив touchна echo:

for d in */*/; do f=${d/\//_}; echo -- "$d"/"${f::-1}.txt"; done
  • for d in */*/позволяет нам перебирать каталоги на два уровня в глубину

  • f=${d/\//_}заменяет первый разделитель каталогов /на _и сохраняет вывод как переменнуюf

  • "$d"/"${f::-1}.txt"расширяется до имени каталога, за которым следует желаемое имя файла; ${f::-1}удаляет последнее /из переменнойf

Обратите внимание, что, поскольку разделитель каталогов /присутствует с переменной d, /in "$d"/"${f::-1}.txt"является избыточным; поскольку почти все системы принимают //как single /, это не должно быть проблемой. В качестве альтернативы, вы можете использовать drip /:

for d in */*/; do f=${d/\//_}; touch -- "${d}${f::-1}.txt"; done

решение2

Если вы хотите, чтобы имена файлов были буквально названы name_date.txt, попробуйте сделать следующее:

#!/bin/bash
for dir in $(find . -maxdepth 2 -mindepth 2 -type d)
do
    touch "$dir"/name_date.txt
done

Если вы хотите, чтобы имена файлов были <name>_<date>.txt, сделайте следующее:

#!/bin/bash
IFS=$'\n'
for dir in $(find . -maxdepth 1 ! -path . -type d)
do
    for subdir in $(find "$dir" -mindepth 1 -type d)
    do
        base_dir=$(basename $dir)
        base_subdir=$(basename $subdir)

        touch "$base_dir"/"$base_subdir"/"$base_dir"_"$base_subdir".txt
    done
done

решение3

find . -type d -exec sh -c '
   case ${1//[!\/]/} in
      "//" ) f=${1:2}; f=${f/\//_}; :> "$1/$f.txt" ;;
      * ) false ;;
   esac
' {} {} \; -prune

for d in */*/; do
   f=${d/\//_}
   :> "${d%?}/${f%?}.txt"
done

Связанный контент