sed 's/123/456/g; w number123' number
Обратите внимание, что он печатает (и записывает в number123
) все строки, включая те, которые не содержат 123
.
Чтобы распечатать только измененные:
sed -e 's/123/456/gw number123' -e t -e d number
Предполагая, что все ваши каталоги находятся в одном родительском элементе, попробуйте следующее:
$ for f in $(ls */accepted_hits.bam); do mv $f $(dirname $f)/$(dirname $f)-$(basename $f); done
Я бы, вероятно, использовал awk
, но это просто вопрос вкуса, а не правильного и неправильного:
find . -name accepted_hits.bam | awk '{ print "cp -pi \"" $0 "\" \"" $0 "\"_" NR "; mv -i \"" $0 "\"_" NR " ./bam-files/" }' | tcsh -f
где вам нужно создать каталог ./ bam-files /
перед вызовом указанной выше строки или измените имя каталога. Я намеренно использовал -p
для сохранения времени файла и -i
, чтобы избежать перезаписи, на всякий случай. Итак, перед повторным вызовом команд очистите целевой каталог.
Если вы хотите удалить исходные файлы, замените cp -pi
на mv -i
.
Сценарий не включает вызовы basename
в надежде столкнуться с меньшими проблемами, если имя пути содержит специальные символы (обрабатываются пробелы и большинство специальных символов).
PS: Вы также можете выполнить пробный прогон перед выполнением, не указав | tcsh -cf
в конце. Если у вас не установлен tcsh
(да, есть Linux без него), не стесняйтесь использовать sh
или bash
.
Если вы просто хотите назвать их уникальными файлами, вы можете использовать переменную RANDOM
, как показано ниже:
find /basedir/ -type f -name "accepted_hits.bam" -exec bash -c 'mv $0 $0.$RANDOM' {} +
Если вы хотите назвать их последовательно, вы можете добавить значение счетчика в конце имени файла, как показано ниже:
for file in $(find /basedir/ -type f -name "accepted_hits.bam"); do ((count++)) ; mv $file ${file}_${count}; done
Два вышеуказанных метода переименовывают файл в том же каталоге. Если вы хотите переименовать их в другой каталог, вы можете объединить их с ответом @schlimmchen (используя basename и dirname). Вы даже можете вставить оператор echo перед командой move, чтобы увидеть результат без фактического перемещения файлов. Я обнаружил, что это удобный способ протестировать команды, не рискуя внести изменения в файлы.
Это очень легко сделать с помощью глобусов оболочки:
Добавьте счетчик в имя ( accept_hits.bam.1
, accept_hits.bam.2
и так далее):
c = 0; для f в * / accept_hits.bam; do mv "$ f" "$ f". $ ((++ c)); done
Это просто перебирает все файлы с именем accept_hits.bam
, которые находятся в подкаталогах текущего каталога, и сохраняет каждый из них как $ f
. Конструкция $ ((++ c))
увеличивает счетчик ( $ c
), поэтому $ f. $ ((++ c))
будет file.1
, file.2
и т. Д., Увеличивается на каждой итерации.
Обратите внимание, что я использую c = 0
в начале. Если вы этого не сделаете, при последующих запусках будет сохранено значение $ c
, и оно будет продолжать увеличиваться.
Добавьте счетчик, но перед расширением ( accept_hits.1.bam
, accept_hits.2.bam
и так далее):
c = 0; для f в * / accept_hits.bam; do
mv "$ f" "$ (dirname" $ f ")" / "$ (basename" $ f ".bam)". $ ((++ c)).bam
done
Команда dirname
возвращает путь к родительскому каталогу файла:
$ dirname / usr / local / bin / apt
/ usr / local / bin
Команда basename
обратная, она удаляет каталог, оставляя только последнюю часть пути, а также может удалить extension:
$ basename /etc/apt/sources.list
sources.list
$ basename /etc/apt/sources.list .list ## remove extension
sources
Итак, mv "$ f" "$ (dirname" $ f ")" / "$ (basename" $ f ".bam)". $ ((++ c)) .bam
переименует файл по своему усмотрению.
Добавьте имя родительского каталога ( accept_hits.dir1.bam
, accept_hits.dir2.bam
или любое другое имя вашего каталога)
для f in * / accept_hits. бац; сделать
dir = "$ (dirname" $ f ")"; mv "$ f" "$ dir" / "$ (basename" $ f ".bam)". "$ dir" .bam
done
Это та же идея, что и выше, только я сохраняю имя каталога как переменную, чтобы упростить его использование как часть имени файла.
Используйте внешние инструменты. Perl переименует, например,
. Стандартное переименование
, которое поставляется с дистрибутивами на основе Debian, не может работать с увеличивающимися счетчиками. Однако я нашел этот , который может. Загрузите сценарий, ссылка на который есть на этой странице, сохраните его как increname
в текущем каталоге и запустите его следующим образом:
perl increname -n 's / .bam / ++ $ c. ".bam" / e '* / accept_hits.bam
С помощью bash
и find
find . -type f -name accepted_hits.bam -exec bash -c \
'i=0; for f; do (( ++i )); mv -- "$f" "${f}_$i"; done' _ {} +