У меня есть несколько файлов в каталоге, которые содержат либо строку "HG-U133A", либо "HG-U133B". Я хотел бы написать скрипт, который может пройти по всем файлам в каталоге и переименовать все файлы "HG-U133A" с префиксом "A_", а все файлы "HG-U133B" с префиксом "B_".
Итак, если это файлы в моем каталоге
> grep "HG-U133[AB]" *
fileA.txt: HG-U133A
fileB.txt: HG-U133A
fileC.txt: HG-U133B
fileD.txt: HG-U133A
fileE.txt: HG-U133B
Я хотел бы написать скрипт, который может переименовать эти файлы в
> ls
A_fileA.txt
A_fileB.txt
B_fileC.txt
A_fileD.txt
B_fileE.txt
Я был бы очень признателен за помощь с этим. Спасибо
решение1
Это портативное решение, которое не попадает подЛовушка Bash номер 1.
for file in *; do
[ -f "$file" ] || continue
grep -q -- HG-U133A "$file" && { mv -- "$file" "A_$file"; continue; }
grep -q -- HG-U133B "$file" && mv -- "$file" "B_$file"
done
Примечания:
*
не соответствует dotfiles, но вы использовали его в своемgrep
вызове, поэтому я предполагаю, что поведение вам подходит или вы знаете, как его изменить.*
соответствует каталогам. Вашgrep
был вызван без опций, которые могли бы заставить его обрабатывать каталоги. Скрипт пропускает все, что не является обычным файлом, и его главная цель — пропустить каталоги и не беспокоиться о запускеgrep
для них (что в любом случае приведет к сбою).- Двойное тире (
--
) объясняется здесь:Что--
означает (двойное тире)? (также известно как «голое двойное тире»)?Это на случай, если имя файла начинается с тире. Если бы мы использовали./*
вместо ,*
нам бы это не понадобилось. - Вы сказали "или ... или ...", я интерпретирую это как "для данного файла совпадет максимум одна строка". Поэтому
continue
после первогоgrep
. Он там для того, чтобы не вызывать второйgrep
понапрасну. - Если вы ожидаете много файлов с
HG-U133B
и только несколько с ,HG-U133A
то рассмотрите возможность тестирования дляHG-U133B
начала.
Преимущества:
- портативность,
- надежность (код должен работать хорошо независимо от имен файлов).
Недостаток:
- Создание хотя бы одного
grep
процесса для каждого обычного файла далеко не оптимально; это может замедлить работу, если файлов для проверки достаточно много.
решение2
bash
Для этого выполните следующие команды :
for file in `grep -l HG-U133A *` ; do mv "$file" "A_$file" ; done
for file in `grep -l HG-U133B *` ; do mv "$file" "B_$file" ; done