for цикл по файлам с пробелами в их именах - PullRequest
0 голосов
/ 07 ноября 2018

У меня есть каталог или заархивированные файлы, каждый из которых содержит группу файлов XML Мне нужно сделать скрипт, который будет извлекать XML-файлы из этих ZIP-файлов, если они содержат определенную строку

for z in `ls /path/to/archives/*.zip`
do for f in `unzip -l $z | grep 'xml' | awk -F" " '{print "$4" "$5}'`
  do r = $( unzip -p $z $f | grep $string )
    if [ '$r' != '' ]
    unzip $z $f
    fi
  done
done

Когда это выполняется, zip-файл A.zip, содержащий файл «my file.xml», заставляет цикл обрабатывать его как 2 файла «my» и «file.xml». Затем unzip пытается извлечь файл my из A.zip, который завершается ошибкой

Есть идеи, как заставить цикл for не рассматривать пространство в имени файла в качестве разделителя?

1 Ответ

0 голосов
/ 07 ноября 2018

Используйте -Z1 параметр unzip вместо -l. Он выводит один файл на строку без дополнительной информации. Вы должны прочитать его вывод вместо того, чтобы зациклить его, чтобы предотвратить разбиение слов. У вас все еще могут быть проблемы с именами файлов, содержащими символ новой строки (но я не смог их сжать, $'a\nb' был сохранен как a^Jb и извлечен как ab).

Кроме того, в вашем if отсутствует then.

Кроме того, не анализируйте выходные данные ls, вы можете перебирать саму маску с разбитым файлом.

Вам не нужно проверять, что grep выводит что-либо, просто запустите его с -q и проверьте его состояние выхода.

Не забудьте заключить в кавычки переменные, которые могут содержать пробелы или другие специальные символы.

for z in /path/to/archives/*.zip ; do
    while IFS= read -r f ;  do
        if unzip -p "$z" "$f" | grep -q "$string" ; then
            unzip "$z" "$f"
        fi
    done < <(unzip -Z1 "$z" '*.xml')
done
...