Знайти файли з подібним ім'ям до папки


1

Я на OS X, і у мене є папка, яка містить декілька підпапок. Є дві речі, які я хочу зробити. Перший полягає в тому, щоб забезпечити, щоб у кожній підпапці був файл у формі [subfolder-name].

Для другої частини, я знаю, як використовувати sed на окремому файлі, щоб зробити те, що мені потрібно, але я маю проблему перевірки того, що файл є, а потім запустіть команду на ньому. Будь-які поради щодо цього можна оцінити.

Примітка: Я не обов'язково потребую повної відповіді, тим більше, що я намагаюся дізнатися тут. Покажчик у правильному напрямку буде добре.

(Я розумію, що для досягнення цієї мети можуть бути кращі способи, ніж командний рядок, але мені потрібно і в майбутньому потрібно буде робити подібні речі на інших системах на основі Unix, тому я краще знаю :)


Я можу дати вам кращу відповідь, якщо ви зробите своє питання більш чітким :-)
ℝaphink

Зрозуміло, що я відформатував ім'я файлу xml таким чином, щоб половина його не з'являлася. Вибач за те! :)
Dan G

Відповіді:


1
#!/bin/bash

# Get directory name from argument, default is . 
DIR=${1:-.}

# For each subfolder in DIR (maxdepth limits to one level in depth)
find "${DIR}" -maxdepth 1 -type d | while read dir; do
    # Check that there is a file called $dir.grade.xml in this dir
    dirname=$(basename "${dir}")
    gradefile="${dirname}"/"${dirname}".grade.xml
    if [ -e "${gradefile}" ]; then
          sed -i .bak "s/foo/bar/g" "${gradefile}"
    else
       echo "Warning: ${dir} does not contain ${gradefile}"
    fi done

Незначні налаштування навколо рамок Рафінка.

Ключові моменти:

  • безпосередньо перевіряти наявність файлу з [ -e filename ] замість того щоб запускати ls
  • помістити всі змінні в ${variablename}; часто не є обов'язковим, але уникає двозначності ( ${variablename} і ${variable}name чітко окреслені, $variablename може означати теж)
  • передайте розширення sed, щоб створити резервні файли. Це хороша практика (у випадку, якщо ваш munging піде не так), і, на OSX, обов'язково (версія raphink інтерпретує s/foo/bar/g як розширення, яке ви бажаєте використовувати у файлах резервних копій, а потім намагаєтеся розібрати назву файлу як команду.
  • Гаразд, я брехав, це не так насправді обов'язково - можна використовувати sed -i "" "s/foo/bar/g" ${gradefile} щоб передати порожнє розширення, що призведе до того, що sed не зробить резервну копію.

Це завжди гарна ідея цитувати змінні, які містять імена файлів. Краще уникати зворотних зв'язків і використання $() замість цього.
Dennis Williamson

Відредаговано, щоб використовувати $ () замість ``, і цитувати змінну, що містить імена файлів, тому що Денніс правильний.
James Polley

0

OK, для цього потрібно створити сценарій. Я виберу для нього баш.

#!/bin/bash

# Get directory name from argument, default is .
DIR=${1:-.}

# For each subfolder in DIR (maxdepth limits to one level in depth)
find $DIR -maxdepth 1 -type d | while read dir; do
    # Check that there is a file called *.xml in this dir
    if ls $dir/*.xml &>/dev/null; then
       # Loop through xml files found in $dir
       #   or do you actually need to check that there is only ONE file?
       for xmlfile in $dir/*xml; do
          # Do whatever treatment with sed you wish to do
          sed -i 's/foo/bar/g' $xmlfile
       done
    else
       echo "Warning: $dir does not have a *xml file in it"
    fi
done

Збережіть цей файл як сценарій .sh, потім запустіть

$ chown +x yourscript.sh
$ ./yourscript.sh /path/to/dir # Path is optional, defaults to .
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.