Не используя дополнительные уровни безопасности как SELinux, Вы не можете сделать этого. Но затем это - плохая идея также, так как существует действительно много других возможностей заблокировать другого пользователя, если можно стать (почти сытыми) корневые права через sudo.
См. https://serverfault.com/questions/36759/editing-sudoers-file-to-restrict-a-users-commands
Можно использовать это sed
команда, чтобы сделать это:
$ sed 's/\([A-Za-z]\)\1\+/\1/g' file.txt
Используя Ваш выше демонстрационного входа я создал файл, sample.txt
.
$ sed 's/\([A-Za-z]\)\1\+/\1/g' sample.txt
NAME
nice - run a program with modified scheduling priority
SYNOPSIS
nice [-n adjustment] [-adjustment] [--adjustment=adjustment] [command [a$
Существует также этот метод, который удалит все дублирующиеся символы:
$ sed 's/\(.\)\1/\1/g' file.txt
$ sed 's/\(.\)\1/\1/g' sample.txt
NAME
nice - run a program with modified scheduling priority
SYNOPSIS
nice [-n adjustment] [-adjustment] [-adjustment=adjustment] [command [a$
OP, который спрашивают, если бы Вы могли бы изменить его так, чтобы только символы верхнего регистра были бы удалены, вот то, как с помощью измененного метода № 1.
$ sed 's/\([A-Z]\)\1\+/\1/g' sample.txt
NAME
nice - run a program with modified scheduling priority
SYNOPSIS
nice [-n adjustment] [-adjustment] [--adjustment=adjustment] [command [a$
Все примеры используют технику, где, когда с символом сначала встречаются, это находится в наборе символов A-Z или a-z, что это - значение, сохраняется. Обертывание parens вокруг символов говорит sed
сохранить их на потом. То значение затем хранится во временной переменной, к которой можно получить доступ или сразу или позже. Эти переменные называют \1 и \2.
Таким образом, прием, который мы используем, мы соответствуем первой букве.
\([A-Za-z]\)
Затем мы оборачиваемся и используем значение, которое мы просто сохранили как вторичный символ, который должен произойти прямо после первого выше, следовательно:
\([A-Za-z]\)\1.
В sed
мы также используем поиск и заменяем средство, s/../../g
. g
средства мы делаем его глобально.
Таким образом, когда мы встречаемся с символом, сопровождаемым другим, мы заменяем им и заменяем его всего одним из того же символа.
Эта команда удаляет все двойные буквы:
sed 's/\([[:alpha:]]\)\1/\1/g'
\1
обозначает текст внутри \(…\)
, так это средство команды: везде, где существует алфавитный символ, сопровождаемый отдельно, замена одним только тем алфавитным символом.
Это преобразует, например. command
в comand
. Было бы лучше ограничить преобразование туда, где это необходимо: строки нес отступом.
sed '/^[[:alpha:]]/ s/\([[:alpha:]]\)\1/\1/g'
Этот текст является страницей справочника, представленной для терминалов, где полужирный представлен наложением: C\bC
представляется как полужирный, где \b
символ возврата (число символов 8, также известный как ^H). Если управляющие символы все еще там, забывают о дублирующихся буквах и вместо этого удаляют наложение.
sed -e 's/.\b//g'
Если у Вас есть способ отформатировать вывод, transofmr C\bC
к полужирному и _\bC
подчеркнуть.
sed -e 's/\(.\)\b\1/\e[1m\1\e[22m/g' -e 's/_\b\(.\)/\e[4m\1\e[24m/g' |
sed -e 's/\e[22m\e[1m//g' -e 's/\e[24m\e[4m//g'
Если Ваш sed не понимает Escape обратной косой черты, используйте буквенные символы (Ctrl+H для \b
и Ctrl + [для \e
).
Это ни в коем случае не тривиальная задача. Простая замена на букву удваивается, имело бы катастрофические последствия. Думайте о том, что это сделало бы к словам как "внимание" или "упущение" или (более относящийся к Вашему случаю) "команда". Сценарий ниже является наивной первой попыткой в решении. Это использует словарь для определения, какие слова действительно имеют дублирующиеся буквы.
#!/usr/bin/perl
use strict;
use warnings;
my $input_file = shift//die "No file name given\n";
my $dictionary = shift//'/usr/share/dict/words';
open my $if,'<',$input_file or die "$input_file: $!\n";
open my $dict,'<',$dictionary or die "$dictionary: $!\n";
my %dictionary;
for(<$dict>){
chomp;
$dictionary{$_}++;
}
close $dictionary;
LINE: while(<$if>){
chomp;
WORD: for my $word ( split /\s+/ ){
print "$word " and next WORD if exists $dictionary{lc $word};
SUBSTITUTION: while($word=~ s{([A-Z])\1}{$1}i){
exists $dictionary{lc $word} and last SUBSTITUTION;
} #END SUBSTITUTION
print "$word ";
} #END WORD
print "\n";
} #END LINE
Назовите его как
[user@host]./myscript.pl input_file optional_dictionary_file >output_file
Если Вы не предоставляете второй аргумент, значения по умолчанию файла словаря к /usr/share/dict/words
, который должен быть доступным на достойном GNU/Linux.
Отказ от ответственности: Это не тестируется.
Протесты:
man
страница самостоятельно.0xFFFF
.SSHHEELLLL GGRRAAMMMMAARR
(от, предположительно, поврежденной страницы удара человека), становятся?
– Joseph R.
11.09.2013, 04:03
Можно ограничить изменения в затронутых строках с чем-то вроде этого:
eval sed $(
for i in NAME SYNOPSIS DESCRIPTION "RETURN VALUE" ENVIRONMENT FILES EXAMPLES DIAGNOSTICS ERRORS "SEE ALSO" "CONFORMING TO" HISTORY AUTHORS BUGS; do
dup=$(for j in $(seq 0 ${#i}); do printf "%s%s" "${i:j:1}" "${i:j:1}"; done)
printf " -e \"s/%s/%s/\"" "$dup" "$i"
done)
В Python:
Метод 1# Используя собственную функцию:
#!/usr/bin/env python
from __future__ import print_function
import sys
def RemoveDupliChar(Word):
NewWord = " "
index = 0
for char in Word:
if char != NewWord[index]:
NewWord += char
index += 1
print(NewWord.strip())
with open(sys.argv[1],'r') as InputFile:
for line in InputFile:
if line.isupper():
RemoveDupliChar(line)
else:
print(line,end='')
Метод 2# Используя itertools.groupby:
Благодаря @falstretu
#!/usr/bin/env python
from __future__ import print_function
import itertools
import sys
with open(sys.argv[1],'r') as InputFile:
for line in InputFile:
if line.isupper():
print(''.join(ch for ch, _ in itertools.groupby(line)))
else:
print(line,end='')
Выполнение:
root@ubuntu:~# python remove_duplicate_char.py Input.txt
NAME
nice - run a program with modified scheduling priority
SYNOPSIS
nice [-n adjustment] [-adjustment] [--adjustment=adjustment] [command [a$
Кажется, ваш пример взят из страниц руководства.
MAN изначально проектировался как телетайп. Для жирного шрифта последовательность будет XX. Вероятно, потерялись при выводе в редактор, отсюда и двойные символы.
vi может легко удалить их.
Попробуйте:
sed -e 's/\([A-Za-z]\)\1/\1/g'
Просто удалите \\\+
, тогда только удвоенные буквы сократятся до одной. (Работает при условии, что все символы были продублированы)
Попробуйте этот небольшой тест:
echo "PPaayy Atttteenttiioonn ttoo aallll ccoommmmaanndds" > test.txt
sed -e 's/\([A-z]\)\1/\1/g' < test.txt > test2.txt
cat test2.txt
sed 's/\([A-Z]\)\1\+/\1/g'
– slm♦ 11.09.2013, 02:45/^[A-Z]/
-sed '/^[A-Z]/s/\(.\)\1/\1/g'
– Kevin 11.09.2013, 04:28sed
, этот ответ удивителен, но можете Вы объяснять. как то, что означает\1
– Rahul Patil 12.09.2013, 19:13