Альтернативное решение, которое использует множество концепций из других ответов и комментариев ...
$ perl -pe 's|(\p{hex}+).*?([^/]+?)$|$2 $1|' DCIM.md5
... и объяснений.
После изучения всех ответов и попытки выяснитьЯ решил, что основа проблемы в том, что [^/]+
является жадным .Его жадность заставляет его захватывать новую строку;он игнорирует якорь $
.
Мне было трудно это понять, поскольку я много раз анализировал с использованием sed
перед использованием Perl, и даже жадный шаблон не будет захватывать новую строку вsed
.Надеюсь, этот пост поможет тем, кто (привык к sed
, как я), также задается вопросом (как и я), почему $
не действует "так, как я ожидаю".
Мыможно увидеть «жадную» проблему, попробовав то, что я опубликую как другой, альтернативный ответ.
Напишите файл:
$ cat > DCIM.md5<<EOF
> e26ff03dc1bac80226e200c0c63d17a2 ./Path1/IMG_20150201_160548.jpg
> 01f92572e4c6f2ea42bd904497e4f939 ./Path 2/IMG_20150204_190528.jpg
> afce027c977944188b4f97c5dd1bd101 ./Path3/Path 4/IMG_20151011_193008.jpg
> EOF
Избавьтесь от жадного [^/]+
, изменив егодо [^/]+?
.Разбор.
$ perl -pe 's|([[:alnum:]]+).*?([^/]+?)$|$2 $1|' DCIM.md5
IMG_20150201_160548.jpg e26ff03dc1bac80226e200c0c63d17a2
IMG_20150204_190528.jpg 01f92572e4c6f2ea42bd904497e4f939
IMG_20151011_193008.jpg afce027c977944188b4f97c5dd1bd101
Требуемый вывод выполнен.
принятый ответ , @Shawn,
$ perl -lpe 's|^([[:alnum:]]+).*?([^/]+)$|$2 $1|' DCIM.md5
в основном изменяет $
якорь, чтобы вести себя так, как ожидал бы sed
человек.
Ответ @CrafterKolyan заботится о жадном [^/]
захвате новой строки, говоря, что у вас не может быть косой черты или новой строки.Этот ответ все еще нуждается в привязке $
, чтобы предотвратить следующую ситуацию
1) .*
захватывает пустую строку ( 0 или более любого символа)
2) [^/\n]+
захватывает .
.
Ответ @Borodin использует совсем другой подход, но это отличная концепция.
@ Бородин, кроме того, сделал отличный комментарий , который позволяет более точную / более точную версию этого ответа, то есть версию, которую я поместил в начале этого поста.
Наконец, если кто-то хочет следовать Perl модель программирования , вот еще один вариант.
$ perl -pe 's|([[:xdigit:]]+).*?([^/]+?)(\n\|\Z)|$2 $1$3|' DCIM.md5
PS Потому что sed
не совсем похоже на perl
( без жадных подстановочных знаков ,) вот пример sed
, который показывает поведение, которое я обсуждаю.
$ sed 's|^\([[:alnum:]]\+\).*/\([^/]\+\)$|\2 \1|' DCIM.md5
Это в основном «прямой перевод» выражения perl
, за исключением для дополнительных '/'
перед [^/]
.Надеюсь, это поможет тем, кто сравнивает sed
и perl
.