次のファイルがあります。
OV2 OVI 1VI OV3 3VI
er 23 23 23 23 23
tr 24 24 24 24 24
最初の列と名前に含まれるすべての列を印刷したいと思いますVI
(どの列に文字列が含まれるかは事前に不明です)。上記の例では、出力は次のようになります。
OVI 1VI 3VI
er 23 23 23
tr 24 24 24
すべての列はタブで区切る必要があります。
ベストアンサー1
perl -lane '$,="\t";
$. == 1 and @A = grep $F[$_] =~ /VI/, 0..$#F;
print @F[0,@A];
' yourfile
結果
ID OVI 1VI 3VI
er 23 23 23
tr 24 24 24
布材
- 最初の行から
$. == 1
文字列を含むフィールドのインデックスを抽出しますVI
。 - 次に、配列内のこれらのインデックスリストを使用して、配列の最初のフィールド+配列にリストされているフィールドを切り取ります
@A
。すでに.YMMVに設定されています。@A
@F
OFS=$,
TAB
アッ
awk -v OFS="\t" '
NR==1{
for ( i=2; i<=NF; i++ )
if ( $i ~ /VI/ )
str = str OFS i
N = split(str, A, OFS)
}{
s = $1
for ( i=2; i<=N; i++ )
s = s OFS $(A[i])
$0 = s
}1
' yourfile
SED
sed -e '
# TAB->spc, multiple spc -> single spc, trim leading/trailing spc
y/ / /;s/[ ]\{2,\}/ /g;s/^[ ][ ]*//;s/[ ][ ]*$//
# only for first line, remove the first field and store remaining in hold area
1{
h
s/[ ]/\
/
s/.*\n//
x
}
# append hold area (which now has 2nd...last fields
# data of the first record) to the present line and
# place a marker at the end of the first field
G
s/[^ ][^ ]*[ ]/&\
/
# setup a do-while loop which progressively either keeps VI data or trims it
:loop
# 1 2 3
s/\(\n\)\([^ ][^ ]*\)[ ]\{0,1\}\(.*\n\)[^ ]*VI[^ ]*[ ]\{0,1\}/ \2\1\3/;tloop
s/\(\n\)[^ ][^ ]*[ ]\{0,1\}\(.*\n\)[^ ][^ ]*[ ]\{0,1\}/\1\2/
/\n\n$/!bloop
# loop ends when the two \ns collide at the end of line
# remove the two \ns and what remains is what you wanted
s///
' yourfile