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
2つのASDFASDF22
sの間の列は50文字未満でなければならず、それ以外の場合は切り捨てる必要があります。
答え1
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;
}'