Нещодавно у командному рядку виникли проблеми з деяким регулярним виразом, і я виявив, що для відповідності зворотної косої риси можна використовувати різні кількості символів. Це число залежить від цитування, використовуваного для регулярного виразу (жодного, одинарного, подвійного лапок). Про те, що я маю на увазі, див. Наступний сеанс баш:
echo "#ab\\cd" > file
grep -E ab\cd file
grep -E ab\\cd file
grep -E ab\\\cd file
grep -E ab\\\\cd file
#ab\cd
grep -E ab\\\\\cd file
#ab\cd
grep -E ab\\\\\\cd file
#ab\cd
grep -E ab\\\\\\\cd file
#ab\cd
grep -E ab\\\\\\\\cd file
grep -E "ab\cd" file
grep -E "ab\\cd" file
grep -E "ab\\\cd" file
#ab\cd
grep -E "ab\\\\cd" file
#ab\cd
grep -E "ab\\\\\cd" file
#ab\cd
grep -E "ab\\\\\\cd" file
#ab\cd
grep -E "ab\\\\\\\cd" file
grep -E 'ab\cd' file
grep -E 'ab\\cd' file
#ab\cd
grep -E 'ab\\\cd' file
#ab\cd
grep -E 'ab\\\\cd' file
Це означає що:
- без жодних лапок, я можу зіставити звороту косу рису з 4-7 фактичними косою рисою
- з подвійними котируваннями я можу зіставити зворотний кут нахилу з 3-6 фактичними косою косою рисою
- За допомогою одиничних лапок я можу зіставити зворотний кут нахилу з 2-3 фактичними косою рисою
Я розумію, що оболонка (зі сторінки bash man) ігнорує один додатковий зворотний кут:
"Нецитується зворотна косою рисою (\) - це символ втечі. Він зберігає буквальне значення наступного символу, який випливає"
Це не стосується прикладів, що цитуються одночасно, тому що в одних цитатах не робиться жодного виходу.
І ще одна зворотна косої риси ігнорується командою grep ("\ c" просто "c" уникнуто, але це точно так само, як "c", оскільки "c" не має особливого значення в регулярному вираженні).
Це пояснює поведінку прикладу з одинарними цитатами, але я не дуже розумію інші два приклади, особливо чому є різниця між нерекламованими рядками з подвійним цитуванням.
Знову цитата зі сторінки bash man:
"Закриття символів у подвійних лапках зберігає буквальне значення всіх символів у лапках, за винятком $,`, \ та, коли розширення історії включено,! "
Я спробував те ж саме з GNU awk (наприклад awk /ab\cd/{print} file
), з тими ж результатами.
Однак Perl показує різні результати (використовуючи напр. perl -ne
"/ab\\cd/"\&\&print file
):
- без жодних лапок, я можу зіставити звороту косу рису з 4-5 фактичними косою косою рисою
- з подвійними котируваннями я можу зіставити зворотний кут нахилу з 3-4 фактичними косою рисою
- За допомогою одиничних лапок я можу зіставити звороту косу рису з двома фактичними косою косою рисою
Чи може хтось пояснити цю різницю між нецитованими та дворядковими рядками регулярного виразів у командному рядку для grep та awk? Мене не так цікавить пояснення поведінки Perl, оскільки я зазвичай не використовую однолінійки Perl.
printf "\ntest"
вставить новий рядок перед "тестом", навіть якщо він"\n"
повинен був бути перекладений"n"
оболонкою, оскільки це подвійні лапки ... (тому очікуваний результат повинен бути, для "\ ntest", "ntest". Ми повинні отримати звичку писати:printf "\\ntest"
абоprintf '\ntest'
, але я якось бачу багато сценарію, спираючись на дивацтва.