Я пришел к выводу, что это невозможно:(
Вы должны иметь пользователя ssh когда-то, где-то, чтобы это работало.
Без пользователя вы не можете управлять дисплеем root.
"...given 35-40 files every night, and I need to extract a part of the filename."
Вы говорите «40 файлов». Но вам нужныимена файлов . Обычно, когда вы «получаете файл», имеется в виду его содержимое. 99% процентов команд работают с содержимым , а не с именем. Как бы вы написали cp $badname-goodcontent newname
. Или сравните mv A B
с ln -s A B
. Сбивая с толку --, вдруг файлы и их имена начинают семантически растворяться.
Вам нужен список ваших ежедневных «партий», чтобы работать с самого начала. Лучше всего было бы создать список, а не имена файлов. Эти файлы вообще служат (другой )цели? (Я вижу, это jpg--)
Начните с ls -f *9000.jpg >resol9000.txt
, затем вы сможете работать с этими строками, как обычный человек.
(У меня нет решения, но я думаю, что это изменение стратегии то, что вам нужно)
(похоже, вы хорошо знаете perl --теперь используйте его для этого временного файла)
(как вы говорите :вам нужен позитивный прогноз. Итак, вам нужен файл)
Нет необходимости переходить от 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
С вашей командой perl
вы всегда печатаете строку, потому что у вас есть опция -p
. Часть match ничего не делает.
Вы хотите -n
и распечатайте соответствующую часть:
ls -1 *9000.jpg \
| perl -lne 'print $1 if /^(.+)(?=_.+_.+)/'
Поскольку в именах файлов могут быть новые строки, вы должны изменить это, чтобы читать нулевые -имена файлов с разделителями, хотя в вашем случае это может не понадобиться:
printf '%s\0' *9000.jpg \
| perl -lne 'INIT{ $/ = "\0"}; print $1 if /^(.+)(?=_.+_.+)/'
В качестве альтернативы можно прочитать имена файлов в цикле for -, после чего вы можете использовать только расширение параметров оболочки:
for f in *9000.jpg; do printf '%s\n' "${f%_*_*}"; done
Возможно, это лучше подходит для вашей задачи. (=> "Не используйте инструменты редактирования текста на основе строки --для имен файлов." @Кусалананда)