단일 텍스트 파일의 단어로 파일을 생성하는 스크립트가 필요합니다.

단일 텍스트 파일의 단어로 파일을 생성하는 스크립트가 필요합니다.

다음과 같은 시나리오가 있는데 Linux 지식이 부족해도 별로 도움이 되지 않습니다.

다음 내용의 YML 값이 포함된 텍스트 파일이 있습니다.

coolregion:
  min: {z: -99613.0, y: 45.0, x: -99805.0}
  flags: {vehicle-place: allow}
  max: {z: 100387.0, y: 127.0, x: 100195.0}
  priority: 0
  type: cuboid
  owners:
    groups: [jacob, eithan, michael]
  members:
    groups: [jack, noah]
niceregion:
      min: {z: 544.0, y: 6.0, x: 184.0}
  flags: {}
  max: {z: 556.0, y: 13.0, x: 197.0}
  priority: 0
  type: cuboid
  owners:
    groups: [noah]
  members:
    groups: [logan, lucas, jack]

각 이름과 그것이 속한 영역에 대한 파일을 생성하고 싶습니다.

예를 들어 noah.txtcoolregion, niceregion( jacob.txt는) 포함되며 coolregion.

나는 정규식을 꽤 잘 알고 있으므로 올바른 방향(예: 정규식만으로 트릭을 수행하는 스크립트)을 알려주시면 기쁠 것입니다.

중요한 경우 내 Linux 버전은 "Debian GNU/Linux 5.0"입니다.

답변1

이것은 awk 솔루션입니다. 저는 YML을 모르므로 정규식을 조작해야 할 수도 있습니다(예: 영역 마커를 들여쓰기할 수 있습니까?). 이 print data >filename구성은 지정된 파일 이름에 처음 도달할 때 파일을 생성하거나 잘라낸 다음 파일에 추가합니다.

<input.yml awk '
/^[^ :]+: *$/ {sub(/: *$/,""); region=$0}     # start of region
/^ *groups:/ {                                # owner or member list
    sub(/^[^:]*: *\[/, ""); sub(/\].*/, "");  # extract bracketed names
    split($0, names, / *, */);                # split comma-separated list
    for (n in names)                          # iterate over names
        print region >names[n] ".txt";        # write or append to name file
}'

너무 심각하게 받아들이지는 않지만 여기에 sed 및 Shell 솔루션이 있습니다.

<input.yml sed -n -e '/^[^ ]/ h' \
                  -e '/^ \+groups:/ {' \
                    -e 'G' \
                    -e 's/^[^:]*: *\[\(.*\)\]\n\(.*\):/\2,\1/' \
                    -e 's/, \+/,/g' \
                    -e 'p' -e '}' | (
  IFS=,; set -f
  while read -r region names; do
    for name in $names; do
      echo "$region" >>"$name.txt"
    done
  done
)

답변2

"펄" 솔루션:

스크립트:

use warnings;                                                                                                                                                                       
use strict;                                                                                                                                                                         

die "Usage: perl $0 file\n" unless @ARGV == 1;                                                                                                                                      

my (%hash, $region);                                                                                                                                                                

open my $fh, "<", $ARGV[0] or die "Cannot open file $ARGV[0]: $!\n";                                                                                                                

while ( my $line = <$fh> ) {                                                                                                                                                        

        ## Get region, characters until first ':' without spaces at the beginning.                                                                                                  
        $region = $1 if $line =~ /^([^:\s]+)/;                                                                                                                                      

        ## Get names with a regex and save them as keys of a hash, values will be                                                                                                   
        ## regions.                                                                                                                                                                 
        if ( $line =~ /^\s*(?i:groups):\s*\[([^\]]*)\]\s*$/ ) {                                                                                                                     
                my @names = split /,\s*/, $1;                                                                                                                                       
                for my $name ( @names ) {                                                                                                                                           
                        push @{ $hash{ $name } }, $region;                                                                                                                          
                }                                                                                                                                                                   
        }                                                                                                                                                                           
}                                                                                                                                                                                   

## Read names (keys of the hash), open a file for each one and write regions on it.                                                                                                 
for my $name ( sort keys %hash ) {                                                                                                                                                  
        my $outfile = $name . ".txt";                                                                                                                                               
        open my $ofh, ">", $outfile or do { warn "Cannot open $outfile: $!\n"; next };                                                                                              
        print $ofh join( ", ", @{ $hash{ $name } } ), "\n";                                                                                                                         
        close $ofh or warn "Cannot close $outfile\n";                                                                                                                               
}                                                                                                                                                                                   

close $fh or warn "Cannot close $ARGV[0]\n";

구현하다:

$ perl script.pl infile

관련 정보