изменить имя файла на основе текущего имени файла, совпадающего с содержимым отдельного файла

Я знаю, что это старый пост, но почему бы просто не сделать это?

echo "hi" >> log.txt #stdout -> log
echo "hi" | tee -a log.txt #stdout -> log & stdout
echo "hi" &>> log.txt #stdout & stderr -> log
echo "hi" |& tee -a log.txt #stdout & stderr -> log & stdout

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

Вы можете сделать это с любой комбинацией потоков, просто используя эти две основные команды.

Я знаю, что я пришел сюда и не получил простой для понимания/реализовать ответ, надеюсь, это поможет кому-то еще, кто борется.

Между прочим, для нубов, таких как мой предыдущий я, все, что делает команда tee, это выводит ввод stdin как на stdout, так и в файл (s ), указанный в качестве последующих аргументов. -aозначает добавление, поэтому вы не перезаписываете файл при каждом использовании команды. Если у вас есть дополнительные вопросы, я считаю этот очень полезным ресурсом для быстрого изучения bash.

0
17.10.2020, 19:41
3 ответа

Вы должны использовать разделитель для файла, содержащего два поля в строке. Здесь sedвставляет этот разделитель, и результат передается строка за строкой в ​​mv

#!/bin/bash
while read -r oldname newname; do
    [ -f "${oldname}.png" ] && echo mv -- "${oldname}.png" "${newname}.png"
done < <(sed 's/^[0-9]*/& /' upcs.txt)

Снимите echoпосле тестирования. Конечно, я предполагаю, что ваше первое поле всегда представляет собой последовательность цифр, а второе поле не имеет пробелов, не начинается с цифры и т. д.

Если вам нужны какие-либо дополнительные действия, например, проверка на наличие повторяющихся имен целей, вы можете сделать это в первую очередь над файлом. Или, если вам нужно, в любом случае mvне перезаписывать существующую цель, используйте -n(--no-clobber), также-i(--interactive)будет запрашивать ввод пользователя по той же причине.

4
18.03.2021, 22:57

Один из способов следующий. Но обратите внимание, что это выглядит файлы только в текущем каталоге и не переходят в подкаталоги.

while IFS= read -r l <&3
do
  barcode=${l%%[!0-9]*}
  value=${l#"$barcode"}
  [ -f "$barcode.png" ] && \
  printf '%s.png ' "$barcode" "$value" 
done 3< upcs.txt | xargs -rn 2 -t cp -pdf --
0
18.03.2021, 22:57

В вашем сценарии переменная $f будет иметь вид 052100029962.png, который не соответствует ни одной из строк upcs.txt:

052100029962.png doesn't match *052100029962mccormickpepper*

Предполагая, что номера UPC всегда имеют длину 12 символов или что названия продуктов не начинаются с цифры, я бы перебирал строки текстового файла, разделял строку с помощью регулярного выражения, искал имя файла {$upc}.png и переименуйте его в {$product _name}.png.

#!/bin/bash
while read -r line; do
    if [[ $line =~ ([0-9]{12})(.*) ]]; then
        upc="${BASH_REMATCH[1]}.png"
        name="${BASH_REMATCH[2]}.png"
        if [[ -f $upc ]]; then
            if [[ ! -f $name ]]; then
                cp "$upc" "$name"
            else
                echo "$name already exists"
            fi
        fi
    fi
done < upcs.txt
2
18.03.2021, 22:57

Теги

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