Найти файлы с похожим именем в папке

794
Dan G

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

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

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

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

1
Я мог бы дать вам лучший ответ, если вы поясните свой вопрос :-) ℝaphink 14 лет назад 0
Понял, что я отформатировал имя xml-файла таким образом, что половина его не появилась. Извини за это! :) Dan G 14 лет назад 0

2 ответа на вопрос

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

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

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

  • проверять напрямую наличие файлов, [ -e filename ]а не запускать ls
  • положить все переменные в $; часто не является строго необходимым, но избегает двусмысленности ( $и $nameявно различимы, $variablenameможет означать и другое)
  • передать расширение для создания резервных копий файлов. Это и хорошая практика (в случае, если ваш манжинг работает неправильно), и, в OSX, обязательная (версия raphink интерпретируется s/foo/bar/gкак расширение, которое вы хотите для файлов резервных копий, затем пытается проанализировать имя файла как команду.
  • Ладно, я соврал, это на самом деле не обязательно - вы можете использовать sed -i "" "s/foo/bar/g" $для передачи пустого расширения, что приведет к тому, что sed не сделает резервную копию.
Всегда хорошая идея заключать в кавычки переменные, которые содержат имена файлов. Лучше избегать обратных кавычек и использовать `$ ()`. Dennis Williamson 14 лет назад 0
Отредактировано, чтобы использовать $ () вместо ``, и заключать в кавычки переменную, которая содержит имена файлов, потому что Деннис правильный. James Polley 14 лет назад 0
0
ℝaphink

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

#!/bin/bash  # Get directory name from argument, default is . DIR=$  # 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 .