Регулярное выражение не может быть указано с опцией -F
относительно grep
. Есть еще одна проблема, связанная с регулярным выражением. Если символ ^
используется в качестве привязки к началу строки, он должен быть первым символом регулярного выражения.
prompt% cp -v input input.back
prompt% grep -e "$regex" input.back > output
prompt% grep -v "$regex" input.back > input
Регулярное выражение:Оригинальный постер не предоставил конкретных входных данных, поэтому трудно найти подходящее регулярное выражение.
Редактировать :, наконец, исходный постер предоставил образец входного файла.
Apple/One-plus/Samsung/Mi/Sony/_Nokia/
Apple/One-plus/Samsung/Mi/Lenovo/_Nokia/
Apple/One-plus/Samsung/Mi/HTC/OPPO/
Регулярное выражение:regex
regex='\([-[:alpha:]]\+\/\)\{5\}_Nokia\/'
Подобные решения не рекомендуются новичкам, которые никогда не читали руководство по sed.
sed -n "/$regex/p;/$regex/d;w input" input.back > output
Грубо говоря,строки, соответствующие регулярному выражению, сохраняются в файле output
, затем удаляются из соответствующего sed-буфера, а содержимое буфера записывается в файл input
.
sed -i.back -e "/$regex/w output" -e "/$regex/d" input
Эти команды имеют небольшие различия, но вторая более удобна.
Реализация GNU printf
или printf
, встроенная в ksh93, zsh или bash, будет делать что-то подобное с printf %q
, выводя строки, как если бы они заключались в кавычки $'...'
ksh93, когда они содержат управляющие символы. например возврат каретки или перевод строки:
$ string=$'foo\rbar\n' ksh93 -c 'printf "%q\n" "$string"'
$'foo\rbar\n'
$ string=$'foo\rbar\n' zsh -c 'printf "%q\n" "$string"'
foo$'\r'bar$'\n'
$ string=$'foo\rbar\n' bash -c 'printf "%q\n" "$string"'
$'foo\rbar\n'
$ string=$'foo\rbar\n'; /usr/bin/printf "%q\n" "$string"
'foo'$'\r''bar'$'\n'
В оболочке zsh
вы также можете использовать флаг расширения параметра qqqq
, чтобы безоговорочно использовать эти $'...'
кавычки:
$ s1=$'\r\n' s2=foobar
$ print -rC1 -- ${(qqqq)s1} ${(qqqq)s2}
$'\r\n'
$'foobar'
В зависимости от вашей оболочки, отладка трассировки может или не может однозначно представлять непечатаемые символы.
x=$(printf a\\rb)
(set -x; LC_ALL=C; : "$x")
приводит к трассировке с использованием нотации $'…'
в оболочках, которые ее поддерживают :например, ksh, mksh и bash all print
+ : $'a\rb'
Но другие оболочки, такие как dash и BusyBox,просто напечатайте символ возврата каретки в стандартную ошибку, что приведет к неоднозначному выводу на терминале, чего, как я понимаю, вы хотите избежать. Если это возможно, запустите скрипт в bash или (m )ksh (или zsh в режиме эмуляции sh )во время отладки.
Некоторые реализации printf имеют спецификатор q
. %q
похож на %s
, но заключает в кавычки некоторые символы таким образом, чтобы вывод можно было проанализировать обратно в оболочку. Результат также визуально однозначен, т.е. вкладки печатаются как \t
. Реализация GNU printf также поддерживает %q
.
LC_ALL=C printf %q\\n "$x"
В dash в Linux необходимо использовать внешнюю утилиту printf:/usr/bin/printf
. В BusyBox эта функция недоступна.
Многие реализации cat
могут выводить непечатаемые -символы визуальным способом, например. вкладки ^I
, а не куча пробелов. Обратите внимание, что это не однозначно :табуляция неотличима от двух символов ^I
.
printf '%s\n' "$x" | cat -vet
Вы можете распечатать вывод с шестнадцатеричным дампом. Портативный способ сделать это с помощью od
.
$ x=$(printf a\\tc\\rb); printf %s "$x" | od -tx1'
0000000 61 09 63 0d 62
0000005
Утилита BSDhexdump
(hd
для краткости ), доступная в *BSD и дистрибутиве Linux, производном от Debian -, также выводит печатные символы, что удобнее.
$ x=$(printf a\\tc\\rb); printf %s "$x" | hd
00000000 61 09 63 0d 62 |a.c.b|
00000005
Популярная утилита xxd
(, распространяемая вместе с Vim, но доступная в виде отдельного пакета в большинстве дистрибутивов ), имеет аналогичный формат вывода.
$ x=$(printf a\\tc\\rb); printf %s "$x" | xxd -g1
00000000: 61 09 63 0d 62 a.c.b
Вы можете перевести все непечатаемые символы один за другим, используя sed. Обратите внимание, что для создания переносимого скрипта вам нужно фактически передать эти печатные символы в sed. Если sed вызывается из сценария оболочки, вы можете использовать printf
для создания сценария sed. Приведенный ниже сценарий выводит наиболее распространенные управляющие символы в виде экранирования обратной косой черты; добавьте больше, если хотите.
#!/bin/sh
export LC_ALL=C
sed_script=$(printf '
s/\\\\/\\\\\\\\/g
s/'\''/\\\\'\''/g
s/\a/\\\\a/g
s/\b/\\\\b/g
s/\t/\\\\t/g
s/\f/\\\\f/g
s/\r/\\\\r/g
s/\033/\\\\e/g
$!s/$/\\\\n/
')
quoted=$(printf %sa "$2" | sed "$sed_script" | tr -d '\n')
printf "%s=\$'%s'\n" "$1" "${quoted%a}"
Использование:quoted-dump x "$x"