Linux에서 bash를 사용하여 출력에서 열이 정렬되도록 특정 열 앞에 공백을 삽입하도록 텍스트 파일을 처리하려면 어떻게 해야 합니까? 예를 들어:
입력하다
1653455 ASDFASDF22 bla bla bla asd xmv ASDFASDF22 AA
1944444 ASDFASDF22 klasdfmxvl yxklc erisa ask xdk asdm ase ASDFASDF22 BB
1984945 ASDFASDF22 jklyck aklsdfl asfjasl asdkkcii wdkkkxd aslasl wqe ASDFASDF22 BB
산출
1653455 ASDFASDF22 bla bla bla asd xmv ASDFASDF22 AA
1944444 ASDFASDF22 klasdfmxvl yxklc erisa ask xdk asdm ase ASDFASDF22 BB
1984945 ASDFASDF22 jklyck aklsdfl asfjasl asdkkcii wdkkkxd aslasl wqe ASDFASDF22 BB
두 ASDFASDF22
s 사이의 열은 50자 미만이어야 하며 그렇지 않으면 잘려야 합니다.
답변1
한 가지 솔루션은 다음을 사용합니다 perl
.
콘텐츠script.pl:
use warnings;
use strict;
## Acept one argumnet, the input file.
@ARGV == 1 or die qq[Usage: perl $0 input-file\n];
while ( <> ) {
## Remove last '\n' char.
chomp;
## Split line with string 'ASDFASDF22'
my @f = split /(ASDFASDF22)/;
## Print line but print first 49 chars plus a space of the special string.
printf qq[%s%-50s%s\n],
join( qq[], @f[0,1] ),
substr( $f[2], 0, 49 ) . qq[ ],
join( qq[], @f[3..$#f] );
}
스크립트를 실행합니다.
perl script.pl infile
그리고 출력:
1653455 ASDFASDF22 bla bla bla asd xmv ASDFASDF22 AA
1944444 ASDFASDF22 klasdfmxvl yxklc erisa ask xdk asdm ase ASDFASDF22 BB
1984945 ASDFASDF22 jklyck aklsdfl asfjasl asdkkcii wdkkkxd aslasl w ASDFASDF22 BB
답변2
Bash를 사용하는 배열
while read -r -a words; do
prefix="${words[0]} ${words[1]}"
idx=${#words[*]}
suffix="${words[$((idx-2))]} ${words[$((idx-1))]}"
unset words[0] words[1] words[$((idx-2))] words[$((idx-1))]
middle="${words[*]}"
printf "%s %-50s %s\n" "$prefix" "${middle:0:50}" "$suffix"
done < filename
답변3
열화가 필요한 텍스트 파일에서 @Birei의 스크립트를 시도했지만 파일에 지정된 구분 기호와 일치하지 않는 일부 줄이 포함되어 있어 실패했습니다(그리고 열화가 필요하지 않았습니다). 따라서 Perl에 대한 지식이 제한되어 있으므로 불일치 행 처리를 피하기 위해 배열 크기에 대한 간단한 검사를 추가했습니다. 다른 사람이 이 변경이 필요한 경우를 대비해 여기에 기본 코드를 게시하겠습니다.
use warnings;
use strict;
## Acept one argumnet, the input file.
@ARGV == 1 or die qq[Usage: perl $0 input-file\n];
while ( <> ) {
## Remove last '\n' char.
chomp;
## Split line with string 'ASDFASDF22'
my @f = split /(ASDFASDF22)/;
my $f = @f;
# check array size to avoid errors on non-matching lines
if ($f > 1)
{
## Print line but print first 49 chars plus a space of the special string.
printf qq[%s%-50s%s\n],
join( qq[], @f[0,1] ),
substr( $f[2], 0, 49 ) . qq[ ],
join( qq[], @f[3..$#f] );
}
else
{
# output non-matching line as-is
print $_ . qq[\n];
}
}
출력 예:
1653455 ASDFASDF22 bla bla bla asd xmv ASDFASDF22 AA
1944444 ASDFASDF22 klasdfmxvl yxklc erisa ask xdk asdm ase ASDFASDF22 BB
######################### non-matching line left alone ##########################
1984945 ASDFASDF22 jklyck aklsdfl asfjasl asdkkcii wdkkkxd aslasl w ASDFASDF22 BB
답변4
GNU awk:
awk -F "[[:space:]]+ASDFASDF22[[:space:]]+" \
'BEGIN { OFS=" ASDFASDF22 "; }
{
$2 = sprintf("%-50s", substr($2, 0, 50));
print;
}'