REGEX Чтобы добавить недостающие цитаты

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

Тем не менее, рассмотрим следующий пример:

Создайте каталог, в котором вы можете экспериментировать, и перейдите в этот каталог:

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}
3
12.11.2018, 16:47
2 ответа

Когда вы запускаете sedбез -E, тогда выражение является базовым регулярным выражением, а группы захвата должны быть записаны как \(...\). Когда вы используете -Eдля включения расширенных регулярных выражений, группы захвата записываются (...).

\внутри [...]является буквальным, поэтому ваше выражение также не будет добавлять двойные кавычки в строки, заканчивающиеся на \. Некоторые другие побеги также не нужны.

Следовательно, вы можете написать свою команду sedкак

sed 's/\([^"]\)$/\1"/'

или как

sed -E 's/([^"])$/\1"/'

Или, используя&:

sed 's/[^"]$/&"/'

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

Несколько других вариантов, не использующих группу захвата:

sed '/[^"]$/ s/$/"/'

Это относится s/$/"/ко всем строкам, которые соответствуют /[^"]$/.

Или, как вариант,

sed '/"$/ !s/$/"/'

Это относится s/$/"/ко всем строкам, которые не соответствуют/"$/(здесь есть небольшое отличие от других подходов в том, что он также добавляет "к пустым строкам ).

Обратите внимание, что во всех случаях флаг gв конце определенно не нужен.

8
27.01.2020, 21:10

Попробуйте sed -e 's|\([^\"]$\)|\1\"|g' bigfile.tsv.

2
27.01.2020, 21:10

Теги

Похожие вопросы