У меня есть много .conf
файлы, которые идентичны и в том же каталоге, за исключением наличия различных имен файлов. В каждом исключительно названном .conf
файл, я хотел бы заменить ряд символов в файле с названием файла. Например:
В настоящее время во всех файлах:
datafname = example.nex
ofprefix = best.example
Идеальный вывод:
Имя файла: 25.conf
datafname = 25.nex
ofprefix = best.25
Имя файла: 26.conf
datafname = 26.nex
ofprefix = best.26
Я думал, что мог использовать sed
пробегать все эти файлы для нахождения и заменения строки текста с именем файла с помощью чего-то как:
sed -i conf 's/example/echo $f/g' *
но это не работает правильно. У кого-либо, оказалось бы, было бы предложение о том, как сделать это?
Можно сделать:
for f in *.conf; do
base=$(basename "$f" '.conf') # gives '25' from '25.conf'
sed -i.before "s/example/$base/g" "$f"
done
При использовании -i
переключатель к sed
, необходимо быть абсолютно уверены что Ваш sed
управляйте работами потому что -i
изменяет оперативные файлы. Это означает, что сгенерированный вывод перезапишет входной файл. Если Ваша заменяющая команда (s/…/…/
) является неправильным, можно закончить с пустыми файлами и никакими резервными копиями. Следовательно, я использовал -i.before
который оставит a *.before
файл с исходным содержанием.
Можно использовать, чтобы цикл выполнил итерации по файлам. Используйте расширение параметра для удаления расширения файла. Используйте двойные кавычки вокруг выражения, иначе переменная не была бы расширена.
#! /bin/bash
for f in *.conf ; do
b=${f%.conf}
sed -i "s/example/$b/" "$f"
done
Можно сделать задачу без цикла с помощью GNU parallel
:
parallel sed -i.old s/example/{.}/ {} ::: *.conf
Это особенно полезно, если у Вас есть много файлов для редактирования, как parallel
выполнения одно задание на ядро процессора.
-i.old
средства: отредактируйте файл i
n-place и делают резервное копирование, добавляющее .old
расширение исходного имени файла (удаляют .old
если Вы не хотите резервное копирование, но помните, что у Вас нет резервного копирования затем),s/example/{.}/g
средства s
замена example
с входным именем файла без его расширения ({.}
) и сделайте это g
lobally (= к каждому происшествию){}
заменяется входным именем файла:::
разделяет команду для выполнения от аргументов для передачи ему*.conf
соответствия каждый .conf
файл в текущем каталогеС awk, который имеет a FILENAME
переменная автоматически набор к имени файла (и, если GNU awk, с редактированиями, оперативными также):
$ for i in {20..26}; do printf "%s\n" "datafname = example.nex" "ofprefix = best.example" > $i.conf; done
$ gawk -i inplace 'FNR == 1 {split(FILENAME, file, ".")} {gsub("example", file[1])} 1' *.conf
$ cat 25.conf
datafname = 25.nex
ofprefix = best.25
FNR == 1 {split(FILENAME, file, ".")}
: на первой строке каждого файла, разделение имя файла на .
и сохраните его в file
массив{gsub("example", file[1])} 1
: для всех строк, замены example
с первым элементом file
массив и печать.