У меня есть следующий небольшой текстовый файл ( mapfile.txt
) на моей Linux-машине. Мне нужно использовать информацию в этом файле, чтобы переименовать другие файлы в других каталогах и подкаталогах. Как я могу это сделать?
Подсказки к вопросам:
1.i need to rename the contents of the file .
2. we should match the any of .config files in the folders and sub folders.The rename should as follows.Column 3 names in the input file should be renamed to column 2 names in the outfile.
3.Yes only the first field should be replaced.
Я пробовал это:
s/search/replace/g
, но это неправильный формат.
mapfile.txt:
PROJECT:DCMS_DEMO:prj1
BLOCK:de_top:blk1
BLOCK:new_block2:blk2
BLOCK:test:blk3
CHECKLIST:Block_DV:checklist1
другие файлы, такие как:
blk3 : 0% : 0%
blk1 : 0.68% : 0.99%
blk2 : 0.00% : 0.00%
OVERALL_STATUS=0.23%
PARTIAL_STATUS=0.33%
Ожидается:
test : 0% : 0%
de_top : 0.68% : 0.99%
new_block2: 0.00% : 0.00%
OVERALL_STATUS=0.23%
PARTIAL_STATUS=0.33%
Сильфонное решение может применяться для замены содержимого файла (или нескольких файлов) .
Во-первых, вы можете выполнить итерацию по файлу карты следующим образом:
while IFS=: read -r desc new old;do #IFS is used to set the delimiter, : in your case
echo "description=$desc - old value:$old - to be replaced with : $new"
#i usually apply this echo as a cross check that all field are read correctly
#more actions here like:
#sed -i "s/$old/$new/g" file1
done <mapfile
Если вы раскомментируете строку над sed, вы вызовете sed внутри цикла, используя переменные, которые вы читаете из файла карты следующим образом:
sed "s / prj1 / DCMS_DEMO / g "
для первой строки файла карты
sed" s / blk1 / de_top / g "
для второй строки файла карты и т. Д.
Это решение имеет ловушку: sed будет вызывается много раз, по одному разу на строку, читаемую из файла карты, поэтому производительность будет медленной.
Чтобы ускорить процесс, вы можете «создать» «сценарий замены», который может подавать sed один раз в конце. Для этого мы можем сделать что-то вроде этого внутри цикла:
echo "s/$old/$new/g;" >>replacements
Когда цикл завершен и весь сценарий замены sed готов, вы можете вызвать sed один раз в конце следующим образом:
sed -f replacements file1
Демонстрация со сценарием замены sed
#!/bin/bash
clear
echo "Original File1"
cat file1
while IFS=: read -r desc new old;do
echo "s/$old/$new/g;" >>replacements
done <mapfile
echo && echo "Replacements for sed"
cat replacements
echo && echo "file1 replaced"
sed -f replacements file1
rm replacements
#Output:
Original File1
blk3 : 0% : 0%
blk1 : 0.68% : 0.99%
blk2 : 0.00% : 0.00%
OVERALL_STATUS=0.23%
PARTIAL_STATUS=0.33%
Replacements for sed
s/prj1/DCMS_DEMO/g;
s/blk1/de_top/g;
s/blk2/new_block2/g;
s/blk3/test/g;
s/checklist1/Block_DV/g;
file1 replaced
test : 0% : 0%
de_top : 0.68% : 0.99%
new_block2 : 0.00% : 0.00%
OVERALL_STATUS=0.23%
PARTIAL_STATUS=0.33%
Советы:
Если вам нужно сделать изменения в файле file1 постоянными, используйте sed -i
Если вам нужно применить тот же сценарий sed к большему количеству файлов в каталоге, вы можете сделать это как:
sed -i -f заменяет * #or / dir / * или * .txt и т. д.
find . -type f -name '*.config' -exec \
perl -wMstrict -Mvars='*h' -F':' -i -pale '
BEGIN {
local(@ARGV, $/) = shift;
chop(local $_ = <>); print;
%h = reverse /^[^:]+:\K(.+?):(.*)$/gm;
}
s//$h{$&}/ if exists $h{ (/\S+/g)[0] };
' mapfile.txt {} +
test : 0% : 0%
de_top : 0.68% : 0.99%
new_block2 : 0.00% : 0.00%
OVERALL_STATUS=0.23%
PARTIAL_STATUS=0.33%
find
находит все файлы, начиная с текущего каталога и далее, просматривает файлы с расширениями .config
и загружает их в Perl
, который открывается в режим редактирования на месте
-i
. Сначала он генерирует хэш отображения из mapfile.txt
, а затем применяет его ко всем последующим файлам в списке аргументов Perl.
find . -type f -name '*.config' -exec \
perl -F: -i -ple '$. == ++$h and $h{$F[2]} = $F[1], 1 or exists $h{(/\S+/g)[0]} and s//$h{$&}/;
$h = 0 if eof' mapfile.txt {} +
With awk
:
awk -F ":" -v OFS=":" 'FNR==NR{a[$3" "]=$2" ";next} $1 in a{ $1=a[$1] };1' mapfile.txt otherfile.txt
O/P:
test : 0% : 0%
de_top : 0.68% : 0.99%
new_block2 : 0.00% : 0.00%
OVERALL_STATUS=0.23%
PARTIAL_STATUS=0.33%