다음과 같은 시나리오가 있는데 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.txt
은 coolregion, 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