Как автоматизировать dos2unix с помощью сценария оболочки?

У меня есть куча файлов xml в каталоге, над которым нужно выполнить команду dos2unix, и время от времени будут добавляться новые файлы. I Вместо того, чтобы каждый раз вручную выполнять команду dos2unix для каждого файла, я хотел бы автоматизировать все это с помощью сценария. Я никогда в своей жизни даже не смотрел на сценарий оболочки, но до сих пор у меня есть это из того, что я прочитал в нескольких учебниках:

FILES=/tmp/testFiles/*
for f in $FILES
do
  fname=`basename $f`
  dos2unix *.xml $f $fname
done

Однако я продолжаю получать вывод «использование». Я думаю, проблема в том, что я неправильно присваиваю имя новому файлу (fname). Может ли кто-нибудь помочь.

Спасибо, Алан


person Alan Smith    schedule 02.07.2012    source источник


Ответы (4)


Причина, по которой вы получаете сообщение об использовании, заключается в том, что dos2unix не принимает дополнительные аргументы, которые вы предоставляете. Однако он будет принимать несколько имен файлов (также через globs). Вам не нужен цикл, если вы не обрабатываете больше файлов, чем может быть принято в командной строке.

dos2unix /tmp/testFiles/*.xml

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

find /tmp/testFiles -name '*.xml' -exec dos2unix {} +

(для поиска GNU)

person Dennis Williamson    schedule 02.07.2012

Если все файлы находятся в одном каталоге (рекурсия не требуется), то вы почти у цели.

for file in /tmp/testFiles/*.xml ; do
    dos2unix "$file"
done

По умолчанию dos2unix должен преобразовываться на месте и перезаписывать оригинал.

Если требуется рекурсия, вам также придется использовать find:

find /tmp/testFiles -name '*.xml' -print0 | while IFS= read -d '' file ; do
    dos2unix "$file"
done

Что будет работать со всеми файлами, оканчивающимися на .xml в /tmp/testFiles/, и со всеми его подкаталогами.

Если никаких других шагов не требуется, вы можете полностью пропустить цикл оболочки:

Нерекурсивный:

find /tmp/testFiles -maxdepth 1 -name '*.xml' -exec dos2unix {} +

И для рекурсивного:

find /tmp/testFiles -name '*.xml' -exec dos2unix {} +

В вашей исходной команде я вижу, что вы находите базовое имя каждого имени файла и пытаетесь передать его dos2unix, но ваши намерения неясны. Позже в комментарии вы говорите, что просто хотите перезаписать файлы. Мое решение выполняет преобразование, не создает резервных копий и перезаписывает оригинал преобразованной версией. Надеюсь, это было вашим намерением.

person sorpigal    schedule 02.07.2012
comment
Он не хранит результаты расширенного глобуса. Глобус не расширяется при назначении. - person Dennis Williamson; 02.07.2012
comment
@DennisWilliamson: я вижу, что ты прав. Я удалил этот комментарий, спасибо за исправление. - person sorpigal; 02.07.2012

mkdir /tmp/testFiles/converted/
for f in /tmp/testFiles/*.xml
do
  fname=`basename $f`
  dos2unix $f ${f/testFiles\//testFiles\/converted\/}
  # or for pure sh:
  # dos2unix $f $(echo $f | sed s@testFiles/@testFiles/converted/@)
done

Результат будет сохранен в подкаталоге converted/.

Здесь используется конструкция ${f/testFiles\//testFiles\/converted\/} (спасибо Rush) или sed для добавления converted/ перед именем файла:

$ echo /tmp/testFiles/1.xml | sed s@testFiles/@testFiles/converted/@
/tmp/testFiles/converted/1.xml
person Igor Chubin    schedule 02.07.2012
comment
Спасибо, но не могли бы вы объяснить, что это делает: $(echo $f | sed s@testFiles/@testFiles/converted/) Редактировать: эта команда не работает. Ошибка: sed: команда искажена: s@testFiles/@testFiles/converted/, удаление команды sed дает ошибку: COuld't open input file FILES - person Alan Smith; 02.07.2012
comment
Я просто добавляю converted/ перед этим именем файла. - person Igor Chubin; 02.07.2012
comment
Вам не нужно sed для этого. Вы можете сделать это с ${f/testFiles\//testFiles\/converted\/} - person rush; 02.07.2012
comment
@Rush: это работает только в bash, а не в оболочке Bourne (/bin/sh) - person Igor Chubin; 02.07.2012
comment
Ребята, я хочу перезаписать файлы, чтобы не было проблем с перемещением новых файлов в другой каталог. Приведенная выше команда не работает. Любые другие предложения? Спасибо. - person Alan Smith; 02.07.2012
comment
Что значит не работает? Какую ошибку вы получаете? Можете, пожалуйста, показать сообщение об ошибке? - person Igor Chubin; 02.07.2012
comment
@AlanSmith: Как насчет find /tmp/testFiles/ -maxdepth 1 -type f -exec dos2unix {} + (если вы не хотите иметь резервную копию)? - person another.anon.coward; 02.07.2012
comment
@IgorChubin: Этот вопрос помечен bash, а не помечен sh, shell или posix-sh, поэтому я думаю, что башизмы приемлемы. - person sorpigal; 02.07.2012

Непонятно, какую реализацию dos2unix вы используете. Разные реализации требуют разных аргументов. Вокруг много разных реализаций.

В RedHat/Fedora/Suse Linux вы можете просто ввести

    dos2unix /tmp/testFiles/*.xml

В SunOS вам необходимо указать имя входного и выходного файла, и приведенная выше команда уничтожит несколько ваших файлов.

Какую версию вы используете?

С уважением, Эрвин

person Erwin Waterlander    schedule 23.12.2012