Нет необходимости переходить от ls
к grep
, чтобы отфильтровать список файлов, вы можете просто
ls *9000.jpg
Также с вашим grep
он выберет любые файлы, которые имеют 9000 в другом месте имени.
С вашим регулярным выражением проблем нет, только с perl
. Используйте grep
и вы получите то, что хотите
ls *9000.jpg | grep -Po "^.+(?=_.+_.+)"
Альтернативный способ сделать это может быть
find. -iname "*9000.jpg" -exec sh -c 'basename ${1%_*_*}' sh {} \;
find
делает то же самое, что иls
Расширение ${1%_*_*}
удаляет символы со второго последнего _
до конца строки, а basename
удаляет путь к файлу, который find
включает в свои результаты.
Конструкция
-exec sh -c `blah blah` sh {} \;
стоит научиться использовать с find
, и у @Kusalananda есть хороший пост здесь
-exec
просто говорит find
делать «бла-бла» с выходными данными, \;
означает делать «бла-бла» с каждым результатом отдельно, sh -c 'put some script in here'
— это то, что вы хотите делать с результатами и, наконец, sh {}
передает вывод из find
обратно в скрипт, определенный вsh -c
Если это должно быть sed
, следующий скрипт работает в соответствии с вашим примером:
#!/usr/bin/sed -f
# if line contains "/*" we enter our "within-patterns" code-block
/\/\*/{
# however, lines must also _not_ contain "*/",
# because our specs wants us to leave those lines as is
/\*\//!{
# first line within patterns, delete everything after the "/*"
s%/\*.*%%
# this is a label to be used by "goto" (sed's 'b' command)
:block
# display current line and read next one
n
# if line just read does _not_ have "*/" end-of-block
/\*\//!{
# delete whole line and
s/.*//
# "goto" label "block" above
bblock
}
# we get here if current line _does_ contain "*/" end-of-block,
# in which case we delete everything up to the "*/"
s%.*\*/%%
# then exit our "within-patterns" code-block.
}
}
Подход заключается в том, чтобы сценарий сохранял контроль над циклом, пока он находится в режиме «внутри блока», вместо того, чтобы позволять sed
делать это автоматически. Таким образом мы точно настраиваем манипуляции со строками внутри блока.
Заметьте, однако, что это только в учебных целях, поэтому познакомим с некоторыми более продвинутыми sed
конструкциями. Этот скрипт не совсем подходит для разбора строк комментариев из реальных исходных файлов C/XML/HTML/любых, потому что они, как правило, намного сложнее, чем ваш пример сценария. См., например, эти вопросы и ответы для получения дополнительной информации .
Судя по ожидаемому результату, вы хотите удалить все символы новой строки, кроме символов новой строки, из блоков, содержащих хотя бы один символ новой строки.
Таким образом, вы можете использовать perl
как:
perl -0777 -pe '
s{/\*.*? \*/ | <--.*? --> | !!.*? !!}{
$& =~ /\n/ ? $& =~ s/[^\n]//gr : $&
}gsex' < your-file