Мне нужно переименовать папки, новые имена в txt файлах внутри каждой папки

Предпочтительнее использовать awk. Хороший лайнер. Но просто показать другое решение:

#!/bin/bash

COUNTER=0
IP=
COMPANY=

nmap -sP 192.168.1.* | while read line
do
    if [[ "$line" =~ ^Nmap ]]; then
        IP=$(echo "$line" | sed -e "s/.*(\(.*\))/\1/")
    fi
    if [[ "$line" =~ ^MAC ]]; then
        COMPANY=$(echo "$line" | sed -e "s/.*(\(.*\))/\1/")
        COUNTER=$((COUNTER+1))
        echo "${COUNTER}. ${COMPANY} (${IP})"
        IP=
        COMPANY=
    fi
done

Объяснение команд sed:

Первая команда sed извлекает IP-адрес из строк в формате Nmap scan report for macbook.att.net (192.168.1.21). Команда sed использует довольно простое регулярное выражение (. Мне также следовало использовать якоря и классы символов, чтобы быть уверенным, что я извлекаю IP-адрес )с помощью группы захвата. Первая часть команды sed (между первой и второй/)— это строка для сопоставления, .*(\(.*\)). .*(соответствует любому (или отсутствию символов ), за которыми следует открывающая скобка. Группа захвата следующая, это \(.*\), которая захватывает любое количество символов (в производственной среде, это должно измениться на регулярное выражение, соответствующее формату IP-адреса ). Концом полного регулярного выражения является один ). Вторая часть команды sed (между второй и третьей/)— это то, чем заменяется регулярное выражение. В данном случае просто \1, что указывает на то, что было в первой группе захвата.

Вторая команда sed в основном то же самое, то есть «сопоставьте строку, содержащую набор скобок в конце, замените всю строку тем, что было внутри скобок».

Сложность заключается в том, что когда вы не используете флаг для использования расширенных регулярных выражений, (и )являются буквальными. Открывать и закрывать скобки. Их нужно экранировать, \(и \), чтобы указать, что они используются для группировки.

Наконец, опция -e, которую я использую в команде.В этом случае это необязательно, так как каждая команда sed имеет только один скрипт/регулярное выражение. У меня привычка всегда им пользоваться.

Рекомендуем к прочтению справочные страницы regex(3), regex(7), которые иногда называют re_format(7), и книгу О'Рейли "Освоение регулярных выражений" Джеффри Фридла.

1
16.10.2020, 03:38
3 ответа

Давайте посмотрим, сработает ли это для вас, если я правильно вас понял:

for i in /path/to/your/dirs/*/info.txt; do
  band=$(awk -F'= ' '/^artist/ { print $2 }' "$i")
  
  song=$(awk -F'= ' '/^name/ { print $2 }' "$i")
  
  folder_name="$band - $song"  

  mv "$(dirname "$i")" "$folder_name"
done
0
18.03.2021, 22:57

Другой способ сделать это (с использованием утилит GNU ). Если этот тест прошел успешно, удалите echo, чтобы запустить его.

#!/bin/sh -
for f in */info.txt; do
    a="$(grep -Pom1 -- "(?<=^artist = ).*" "$f")"
    n="$(grep -Pom1 -- "(?<=^name = ).*" "$f")"
    echo mv -T -- "${f%/*}" "$a - $n"
done

Также здесь хорошо -T. Поведение по умолчанию mvзаключается в переименовании каталога, если цель не существует, и перемещении всего каталога внутрь цели, если цель существует. Таким образом, с -Tв случае любой существующей цели во время этого ничего не будет перемещено.

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

1
18.03.2021, 22:57

Есть еще один способ, не требующий многократного чтения файла info.txt:

#!/usr/bin/env bash

## Give a list of target folders in the command line
for dir in "$@"; do
 . <(awk -F'=' '$1=="artist" || $1=="name"{
                      sub(/^ /,"",$2); 
                      print $1"=\""$2"\""
                 }' "$dir/info.txt")
  mv -- "$dir" "$artist - $name"
done

Сохраните это как foo.sh, сделайте его исполняемым и запустите:

foo.sh path/to/dir1 path/to/dir2... path/to/dirN

Или просто запустите его прямо в терминале:

for dir in path/to/dir1 path/to/dir2... path/to/dirN; do
 . <(awk -F'=' '$1=="artist" || $1=="name"{
                      sub(/^ /,"",$2); 
                      print $1"=\""$2"\""
                 }' "$dir/info.txt")
  mv -- "$dir" "$artist - $name"
done
0
18.03.2021, 22:57

Теги

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