В качестве заявления об отказе от ответственности будьте осторожны при пакетном изменении разрешений. Если у вас есть ошибка в скрипте, который меняет разрешения, это может быть неприятно.
Тем не менее, рассмотрим следующий пример:
Создайте каталог, в котором вы можете экспериментировать, и перейдите в этот каталог:
mkdir /tmp/experiment
cd /tmp/experiment
Создайте группу файлов в каталогах:
mkdir -p {a,b,c,d}/{e,f,g,h}/{i,j,k,l}
touch {a,b,c,d}/{m,n,o,p}
touch {a,b,c,d}/{e,f,g,h}/{q,r,s,t}
touch {a,b,c,d}/{e,f,g,h}/{i,j,k,l}/{u,v,w,x}
В качестве эксперимента предоставьте все файлы случайные разрешения
for i in $(find . -type f); do
chmod $(($RANDOM % 8))$(($RANDOM % 8))$(($RANDOM % 8)) $i
done
Также дайте каталогам случайные разрешения, но сохраните разрешения для владельца:
for i in $(find . -type d); do
chmod 7$(($RANDOM % 8))$(($RANDOM % 8)) $i
done
Создайте сценарий восстановления разрешений, используя stat
:
find . | xargs stat --printf="chmod %a %n\n" > /tmp/perms.sh
Обратите внимание на выходной формат:
head -n3 /tmp/perms.sh
chmod 715 .
chmod 700 ./b
chmod 250 ./b/n
Теперь удалите разрешения:
find . | xargs chmod 777
Теперь вы можете восстановить разрешения с помощью сценария:
bash /tmp/perms.sh
Чтобы убедиться, что это работает, вы можете найти новые разрешения так же, как и раньше, но сохранить их в другом файле:
find . | xargs stat --printf="chmod %a %n\n" > /tmp/perms.sh_new
Затем сравните два файла, а не то, что нет никаких различий:
diff /tmp/perms.sh{,_new}
Когда вы запускаете sed
без -E
, тогда выражение является базовым регулярным выражением, а группы захвата должны быть записаны как \(...\)
. Когда вы используете -E
для включения расширенных регулярных выражений, группы захвата записываются (...)
.
\
внутри [...]
является буквальным, поэтому ваше выражение также не будет добавлять двойные кавычки в строки, заканчивающиеся на \
. Некоторые другие побеги также не нужны.
Следовательно, вы можете написать свою команду sed
как
sed 's/\([^"]\)$/\1"/'
или как
sed -E 's/([^"])$/\1"/'
Или, используя&
:
sed 's/[^"]$/&"/'
&
в замещающей части выражения будет заменено частью ввода, совпадающей с регулярным выражением.
Несколько других вариантов, не использующих группу захвата:
sed '/[^"]$/ s/$/"/'
Это относится s/$/"/
ко всем строкам, которые соответствуют /[^"]$/
.
Или, как вариант,
sed '/"$/ !s/$/"/'
Это относится s/$/"/
ко всем строкам, которые не соответствуют/"$/
(здесь есть небольшое отличие от других подходов в том, что он также добавляет "
к пустым строкам ).
Обратите внимание, что во всех случаях флаг g
в конце определенно не нужен.