#bash #sed #text-processing
#bash #sed #обработка текста
Вопрос:
У меня есть несколько файлов в разных подкаталогах, где один подкаталог содержит файл с правильной информацией в 6-й строке, а остальные содержат только фиктивную информацию. Структура каталогов выглядит следующим образом:
Folder-1
Subfolder-1
File-A
SubfFolder-2
File-B
Subfolder-3
File-B
Folder-2
...
Folder-3
...
File-A
in Subfolder-1
содержит правильный текст в строке 6, который является строкой, которая отличается для каждого Folder
. File-B
содержит фиктивный текст
E1 E2 E3 E4 E5 N
в строке 6. Этот фиктивный текст также идентичен в каждом Folder
. Мне нужно заменить эту фиктивную строку правильной строкой в каждом Folder
, чтобы каждая File
из Folder
них содержала одну и ту же строку в строке 6.
Я предполагаю, что sed
это правильный инструмент для этого, но я не знаю, как настроить его на использование разных строк в качестве входных данных. Основой будет
sed -i 's/String1/String2/g' file
Грубый набросок, который я представляю, это:
for i in */;
do for j in 2 3;
do sed 6th line in "$i"Subfolder-1/File-A > 6th line in "$i"Subfolder-"$j"/File-B % Magic needed
done
done
Ответ №1:
Sed может печатать определенную строку в файле:
sed -n '6p' file
# store it to a variable via
replacement=$(sed -n '6p' file)
Вместо замены (которая не будет работать хорошо, если ваша 6-я строка соответствует другим строкам в вашем файле), вы можете удалить старую 6-ю строку и вставить новую 6-ю строку перед строкой 7:
sed -i -e '6d' -e "7i$replacement" file
Ответ №2:
Давайте рассмотрим это поэтапно.
Нам понадобится find
команда. Чтобы найти все папки:
find . -name "Folder-*"
Пока все хорошо. Теперь, чтобы что-то сделать с каждой папкой:
find . -name "Folder-*" | while read dname; do
echo $dname
done
Теперь, чтобы извлечь правильную строку из File-A:
find . -name "Folder-*" | while read dname; do
echo $dname
good=`sed -n '6p' $dname/Subfolder-1/File-A`
echo $good
done
Теперь, чтобы найти все файлы-Bs, используя внутренний find
, специфичный для папки:
find . -name "Folder-*" | while read dname; do
echo $dname
find $dname -name File-B
done
Теперь, чтобы изменить каждый из этих файлов find
, выполнив внутреннюю sed
команду, заменив каждую шестую строку на «заполнитель»:
find . -name "Folder-*" | while read dname; do
echo $dname
find $dname -name File-B -exec sed -i '' "6s/.*/placeholder/" {} ;
done
Теперь, чтобы собрать все это вместе и использовать переменную good
:
find . -name "Folder-*" | while read dname; do
good=`sed -n '6p' $dname/Subfolder-1/File-A`
find $dname -name File-B -exec sed -i '' "6s/.*/$good/" {} ;
done