1

Я на OS X, и у меня есть папка, которая содержит несколько подпапок. Есть две вещи, которые я хочу сделать. Во-первых, убедитесь, что в каждой подпапке есть файл в форме [subfolder-name] .grade.xml, а затем мне нужно выполнить поиск и замену в соответствующем файле, чтобы внести пару изменений.

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

Примечание: мне не обязательно нужен полный ответ, тем более что я пытаюсь учиться здесь. Хотя указатель в правильном направлении был бы хорош.

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

2 ответа2

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

Незначительные изменения в структуре Raphink.

Ключевые моменты:

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

ОК, вам нужно сделать сценарий для этого. Я выберу Баш для этого.

#!/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 .

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .