Как я использую имена файлов в команде sed?

У меня есть много .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' *

но это не работает правильно. У кого-либо, оказалось бы, было бы предложение о том, как сделать это?

7
задан 4 March 2018 в 13:33

4 ответа

Можно сделать:

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 файл с исходным содержанием.

9
ответ дан 23 November 2019 в 06:13

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

#! /bin/bash
for f in *.conf ; do
    b=${f%.conf}
    sed -i "s/example/$b/" "$f"
done
5
ответ дан 23 November 2019 в 06:13

Можно сделать задачу без цикла с помощью GNU parallel Install parallel:

parallel sed -i.old s/example/{.}/ {} ::: *.conf

Это особенно полезно, если у Вас есть много файлов для редактирования, как parallel выполнения одно задание на ядро процессора.

  • -i.old средства: отредактируйте файл in-place и делают резервное копирование, добавляющее .old расширение исходного имени файла (удаляют .old если Вы не хотите резервное копирование, но помните, что у Вас нет резервного копирования затем),
  • s/example/{.}/g средства sзамена example с входным именем файла без его расширения ({.}) и сделайте это globally (= к каждому происшествию)
  • {} заменяется входным именем файла
  • ::: разделяет команду для выполнения от аргументов для передачи ему
  • *.conf соответствия каждый .conf файл в текущем каталоге
2
ответ дан 23 November 2019 в 06:13

С 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 массив и печать.
1
ответ дан 23 November 2019 в 06:13

Другие вопросы по тегам:

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