Как я выполняю команду на данной строке в каждой строке файла?

Используя dirname и базовое имя любят упомянутый Michael, должен быть самый безопасный способ получить то, что Вы хотите.

Так или иначе, если Вы действительно хотите сделать это с "ударом только инструменты", Вы могли бы использовать замену параметра:

echo `basename $PWD`        # Basename of current working directory.
echo "${PWD##*/}"           # Basename of current working directory.
echo
echo `basename $0`          # Name of script.
echo $0                     # Name of script.
echo "${0##*/}"             # Name of script.
echo
filename=test.data
echo "${filename##*.}"      # data
                            # Extension of filename.

Этот пример непосредственно взят из Усовершенствованного Руководства по созданию сценариев Bash, которое является достойное внимания.

Объяснение довольно просто:

$ {var#Pattern} Удаляют из $var самую короткую часть $Pattern, который соответствует фронтэнду $var. $ {var##Pattern} Удаляют из $var самую длинную часть $Pattern, который соответствует фронтэнду $var.

Посмотрите на шаблон как некоторый regex и # или ## как некоторый greedy/non-greedy модификатор.

Это могло бы стать полезным, если необходимо будет сделать некоторые более сложные извлечения части путей.

2
01.09.2011, 17:43
3 ответа

ls $(awk '{print $3}' /path/to/your/file)

проверьте, работает ли это как ожидалось, и затем замените ls с rm

6
27.01.2020, 21:55
  • 1
    Пока в имени файла никогда не будет пробелов... +1 –  Peter.O 01.09.2011, 17:44
  • 2
    Это решит любой пробельный вопрос. awk '{sub(/^LUN Path: /, ""); print; }' –  Peter.O 01.09.2011, 17:59
  • 3
    @fred нет, это недостаточно: любой пробел и globbing символы закончатся проанализированные оболочкой. Этот сценарий работает, только если нет никакого пробела или globbing символов в именах файлов так или иначе. Это могло легко быть зафиксировано путем добавления обратных косых черт перед проблематичными символами перед печатью. –  Gilles 'SO- stop being evil' 02.09.2011, 02:11
  • 4
    большое спасибо для Ваших ответов. это получило то, что я хотел. –  user10414 03.09.2011, 09:59
echo rm $(sed -n -e 's/[^A-Za-z0-9]/\\&/g' -e 's/LUN Path:  *//p')

Первое s команда добавляет обратную косую черту перед каждым символом, который не является новой строкой, буквой или цифрой. Вторая команда разделяет LUN Path: префикс от строк, которые имеют его и распечатывают только строки, которые имеют префикс. Получившая строка подвергается расширению имени файла и разделению слова в оболочке; так как всех проблематичных символов кроме новых строк оставили, надлежащие имена файлов будут переданы команде.

0
27.01.2020, 21:55
  • 1
    я не получил этот regex. Где new-line обработанный в части [^A-Za-z0-9]? –  Abhishek A 02.09.2011, 16:00
  • 2
    @greenmang0 Sed обрабатывает свой вход линию за линией. regexp подобран против тела строки. С тех пор существует один файл на строку во входе, существует все еще один файл на строку в выводе. –  Gilles 'SO- stop being evil' 02.09.2011, 22:32
cut -d: -f3 file | xargs rm

Команда cutвыберет третье:-поле с разделителями из файла (имя файла после servernam:), в то время как команда xargsпрочитает эти пути с разделителями новой строки -и передаст их в rm.

Если вы хотите, чтобы servernam:был частью фактического пути, замените команду cutна awk '{ print $NF }', которая будет извлекать последнее поле с разделителями -из пробелов в каждой строке.

Это использование cutпредполагает, что в именах путей нет :, а использование awkпредполагает, что пути не содержат пробелов.

0
27.01.2020, 21:55

Теги

Похожие вопросы