BASH скрипт - выполнить команду с переменной и сохранить результат - PullRequest
7 голосов
/ 30 ноября 2011

Я не знаю, как выполнить команду с переменной и получить результат этого.У меня есть много файлов .h и .c, и мне нужно конвертировать каждый из ISO-8859 в UTF-8.

Итак, я делаю:

ls | grep "\.[ch]" | xargs myscript.sh

И в моем сценарии переменная$1 - это имя файла.Теперь мне нужно выполнить

iconv -f ISO-8859 -t UTF-8 $1

и сохранить результат этого, потому что iconv print to stdout.

result=`iconv -f ISO-8859 -t UTF-8 $1`

echo $result 

Это, кажется, не работает, потому что это дает мне некоторое несоответствиевместо преобразованных $1.

Ответы [ 3 ]

7 голосов
/ 30 ноября 2011

Если вам нужно сначала выполнить какое-то преобразование данных, вы можете «захватить» вывод с помощью следующего синтаксиса:

result="$(iconv -f ISO-8859 -t UTF-8 $1)"

Здесь есть и уловка: если вы собираетесь хранить большие объемы данных с потенциальным пробелом или другими мешающими символами, обязательно всегда указывайте переменную ("$result" вместо $result) в убедитесь, что он обрабатывается как одна строка.

3 голосов
/ 30 ноября 2011

Вот решение, которое обрабатывает даже новые строки:

find -name '*.[ch]' \
    -exec mv '{}' '{}.backup' \; \
    -exec iconv -f ISO-8859 -t UTF-8 '{}.backup' -o '{}' \;

Как правило, НИКОГДА не анализируйте имена файлов, если вы собираетесь использовать результаты.Единственные вменяемые способы, о которых я знаю, это

  1. Используйте оболочки-оболочки, например for file in ./*.[ch] ; do echo "$file" ; done.Работает только для одного каталога.
  2. Использовать поиск в сочетании с -exec
  3. Использовать поиск в сочетании с -print0 (который печатает имена файлов как строки, разделенные \ 0) и использовать выходные данные для построениякомандные строки с xargs -0 и, вероятно, вспомогательный скрипт.Это довольно громоздко, однако.

Кроме того, убедитесь, что к относительным именам файлов, которые вы используете, добавлен префикс ./.Вызов mv -from -to небезопасен, но mv ./-from ./-to есть и делает то, что вы хотите.Например, когда вы теретесь, используйте ./*.c вместо *.c.

3 голосов
/ 30 ноября 2011

Я бы сделал так:

while read filename; 
do
    mv "$filename" "$filename.bck" && \
        iconv -f ISO-8859 -t UTF-8 "$filename.bck" > "$filename"
done < find -iname '*.[hc]'

Это создает резервные копии на лету, а также обрабатывает файлы с пробелами (не символы новой строки).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...