Удалить с начала до определенной части в строке - PullRequest
0 голосов
/ 16 июня 2011

Я работаю со строками, такими как

abc_dsdsds_ss_gsgsdsfsdf_ewew_wewewewewew_adf

, и мне нужно получить новую, где я удаляю в исходной строке все от начала до последнего появления символа _ и следующих символов (можетбыть 3, 4 или любым другим числом)

, поэтому в этом случае я получу

_adf

Как я могу сделать это с помощью "sed" или другого инструмента bash?

Ответы [ 8 ]

5 голосов
/ 16 июня 2011

Соответствие шаблону регулярного выражения является жадным. Следовательно, ^. * _ Будет соответствовать всем символам до и включая последний _. Затем просто вставьте подчеркивание обратно:

echo abc_dsdsds_ss_gsgsdsfsdf_ewew_wewewewewew_adf | sed 's/^.*_/_/'
1 голос
/ 16 июня 2011

Если у вас есть подобные строки в переменных bash (я не вижу, что указано в вопросе), вы можете использовать расширение параметра :

s="abc_dsdsds_ss_gsgsdsfsdf_ewew_wewewewewew_adf"
t="_${s##*_}"
echo "$t"  # ==> _adf
1 голос
/ 16 июня 2011

В Perl вы можете сделать это:

my $string = "abc_dsdsds_ss_gsgsdsfsdf_ewew_wewewewewew_adf";

if ( $string =~ m/(_[^_]+)$/ ) {
    print $1;
}

[Изменить] Подход Perl One Liner (то есть, может быть запущен непосредственно из Bash):

perl -lne 'm/(_[^_]+)$/ && print $1;' infile > outfile

Или с использованием подстановки:

perl -pe 's/.*(_[^_]+)$/$1/' infile > outfile
1 голос
/ 16 июня 2011

Вам нужно изменить строку или просто найти все после последнего подчеркивания?Регулярное выражение для поиска последнего _ {что-нибудь} будет /(_[^_]+)$/ ($ соответствует концу строки), или, если вы также хотите сопоставить завершающее подчеркивание с ничем после него, /(_[^_]*)$/.

Если вам действительно не нужно изменять строку вместо того, чтобы просто находить этот фрагмент, или вы действительно хотите сделать это из командной строки вместо сценария, это регулярное выражение немного проще (вы пометили это какperl, так что я не совсем уверен, насколько вы привержены использованию только командной строки, в отличие от простого сценария, которым вы были).

Если вам нужно изменить строку на месте, sed -i 's/(_[^_]+)$/\1/' myfile или sed -i 's/(_[^_]+)$/\1/g' myfile.-i (правка: я решил не лениться и посмотреть правильный синтаксис ...) флаг -i просто перезапишет старый файл новым.Если вы хотите создать новый файл, а не ударить старый, sed -e 's/.../.../g' oldfile > newfile.g после s/// сделает это для всех экземпляров файла, который вы передаете в sed;оставив его, он просто заменяет первый экземпляр.

Если строка не сама по себе в конце строки, а скорее встроена в другой текст.но только через пробел замените $ на \s, который будет соответствовать символу пробела (конец слова).

1 голос
/ 16 июня 2011

Просто сгруппируйте последние символы не подчеркивания, которым предшествует последнее подчеркивание, с \(_[^_]*\), затем укажите ссылку на эту группу с \1:

 sed 's/^.*\(_[^_]*\)$/\1/'

Результат:

$ echo abc_dsdsds_ss_gsgsdsfsdf_ewew_wewewewewew_adf | sed 's/^.*\(_[^_]*\)$/\1/'
_adf
1 голос
/ 16 июня 2011
sed 's/^(.*)_([^_]*)$/_\2/' < input.txt
0 голосов
/ 17 июня 2011

Просто для удовольствия:

echo abc_dsdsds_ss_gsgsdsfsdf_ewew_wewewewewew_adf | tr _ '\n' | tail -n 1 | rev | tr '\n' _ | rev
0 голосов
/ 16 июня 2011

Способ Perl:

echo 'abc_dsdsds_ss_gsgsdsfsdf_ewew_wewewewewew_adf' | \
perl -e 'print ((split/(_)/,<>)[-2..-1])'

выход:

_adf
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...