Home > Blockchain >  awk from file using echo and output to file
awk from file using echo and output to file

Time:05-17

A.txt contains:

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

B.txt contains:

555
777

I want to create the loop, for each string found in B.txt, then output the '/*'[the string] until right before the first '@@@' met to each own file (the string name is also used as file name). So based on the sample above, the result should be :

555.txt, which contains:

/*555*/
hfawehfihohawe
aweihfiwahif
aiwehfwwh

and 777.txt, which contains:

/*777*/
jawejfiawjia
ajwiejfjeiie
eiuehhawefjj

I tried this script but it outputs nothing:

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

Thank you in advance

CodePudding user response:

Making a few alterations to your code provides the desired outcome with the example data provided:

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

Does this solve your problem?

CodePudding user response:

With your shown samples, please try following awk code. Written and tested in GNU awk should work in any 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

Explanation: Adding detailed explanation for above code.

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.
  • Related