Awk из файла с использованием эха и вывода в файл

.txt содержит:

/*333*/
asdfasdfadfg
sadfasdfasgadas
@@@
/*555*/
hfawehfihohawe
aweihfiwahif
aiwehfwwh
@@@
/*777*/
jawejfiawjia
ajwiejfjeiie
eiuehhawefjj
@@@

B.txt содержит:

555
777

Я хочу создать цикл для каждой строки, найденной в B.txt, а затем вывести «/*» [строка] до тех пор, пока не встретится первый «@@@» с каждым собственным файлом (имя строки также используется как имя файла). Таким образом, на основе приведенного выше примера результат должен быть:

555.txt, который содержит:

/*555*/
hfawehfihohawe
aweihfiwahif
aiwehfwwh

и 777.txt, который содержит:

/*777*/
jawejfiawjia
ajwiejfjeiie
eiuehhawefjj

Я пробовал этот скрипт, но он ничего не выводит:

for i in `cat B.txt`; do echo $i | awk '/{print "/*"$1}/{flag=1} /@@@/{flag=0} flag' A.txt > $i.txt; done

заранее спасибо

Шаблон /{print "/*"$1} выбирает каждую строку, содержащую строку {Распечатать "/*", за которой следует содержимое первого поля строки. Это не имеет смысла.

user1934428 17.05.2022 07:39
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
1
1
56
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Внесение нескольких изменений в ваш код обеспечивает желаемый результат с предоставленными примерными данными:

while read -r f
do
    awk -v var="/[*]$f[*]/" '$0 ~ var {flag=1} /@@@/{flag=0} flag' A.txt > "$f".txt
done < B.txt

cat 555.txt
/*555*/
hfawehfihohawe
aweihfiwahif
aiwehfwwh

cat 777.txt
jawejfiawjia
ajwiejfjeiie
eiuehhawefjj

Это решает вашу проблему?

Возможно, awk -v var="/[*]$f[*]/ .... будет более точным, хотя разница не имеет значения для примера данных, размещенных здесь.

user1934428 17.05.2022 07:43

Да, отличная мысль @user1934428 - так будет лучше - я отредактирую свой ответ. Спасибо!

jared_mamrot 17.05.2022 07:49

С показанными образцами попробуйте следовать коду awk. Написано и протестировано в GNU awk, должно работать в любом awk.

awk '
FNR==NR{
  if($0~/^\/\*/){
    line=$0
    gsub(/^\/\*|\*\/$/,"",line)
    arr[++count]=$0
    arr1[line]=count
    next
  }
  arr[count]=(arr[count]?arr[count] ORS:"") $0
  next
}
($0 in arr1){
  outputFile=$0".txt"
  print arr[arr1[$0]] >> (outputFile)
  close(outputFile)
}
' file1 file2

Объяснение: Добавление подробного объяснения кода выше.

awk '                                   ##Starting awk program from here.
FNR==NR{                                ##Checking condition FNR==NR which will be TRUE when file1 is being read.
  if($0~/^\/\*/){                       ##Checking condition if current line starts with /* then do following.
    line=$0                             ##Setting $0 to line variable here.
    gsub(/^\/\*|\*\/$/,"",line)         ##using gsub to globally substitute starting /* and ending */ with NULL in line here.
    arr[++count]=$0                     ##Creating arr with index of ++count and value is $0.
    arr1[line]=count                    ##Creating arr1 with index of line and value of count.
    next                                ##next will skip all further statements from here.
  }
  arr[count]=(arr[count]?arr[count] ORS:"") $0  ##Creating arr with index of count and keep appending values of same count values with current line value.
  next                                  ##next will skip all further statements from here.
}
($0 in arr1){                           ##checking if current line is present in arr1 then do following.
  outputFile=$0".txt"                   ##Creating outputFile with current line .txt value here.
  print arr[arr1[$0]] >> (outputFile)   ##Printing arr value with index of arr1[$0] to outputFile.
  close(outputFile)                     ##Closing outputFile in backend to avoid too many opened files error.
}
' file1 file2                           ##Mentioning Input_file names here.

Вот еще одно awk решение для этого:

awk '
FNR == NR {
   map["/*" $0 "*/"] = $0
   next
}
$0 in map {
   fn = map[$0] ".txt"
}
/^@@@$/ {
   close(fn)
   fn = ""
}
fn {print > fn}' B.txt A.txt

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