我有一個由7個以制表符分隔的列組成的文本檔案。每一列都有不同數量的行,這些行的值可能是重復的。我想洗掉這些重復的值,以便每一列只有該特定列的唯一值。舉個例子:
輸入
C1 C2 C3 C4 C5 C6 C7
111 111 222 333 111 222 777
222 111 333 333 222 333 666
222 111 444 111 333 555 555
333 444 555 222 444 666 444
444 666 555 777 555 666 333
444 777 777 555 666 888 333
777 888 999 666 888
999
輸出
C1 C2 C3 C4 C5 C6 C7
111 111 222 333 111 222 777
222 444 333 111 222 333 666
333 666 444 222 333 555 555
444 777 555 777 444 666 444
777 888 777 555 555 888 333
999 999 666 666
888
我想我需要使用awk來列印每一列,并分別使用sort -u,然后將這些輸出粘貼在一起。那么,有沒有一種方法可以讓一個文本檔案中的i列回圈,列印每一列|排序-u,然后把它們粘貼在一起?
預先感謝。 卡洛斯
CodePudding
使用perl來代替它對真正多維陣列的支持:
perl -lane '
for my $n (0..$#F) {
如果(!存在${$vals[$n]}{$F[$n]}){
push @{$cols[$n]}, $F[$n];
${$vals[$n]}{$F[$n]} = 1;
}
}
END {
for (1...$. ) {
my @row;
for my $n (0..$#cols) {
push @row, shift @{$cols[$n]};
}
print join(" ", @row)。
}
}' input.txt
uj5u.com熱心網友回復:
在每個Unix盒子上的任何shell中使用任何awk:
$ cat tst.awk
開始 { fs=ofs=" " }
{
for (colNr=1; colNr<=NF; colNr ) {
val = $colNr
if ( !seed[colNr,val] ) {
rowNr = colRowNrs[colNr] 。
vals[rowNr,colNr] = val
numRows = (rowNr > numRows ? rowNr : numRows)
}
}
numCols = (NF > numCols ? NF : numCols)
}
END {
for (rowNr=1; rowNr<=numRows; rowNr ) {
for (colNr=1; colNr<=numCols; colNr ) {
val = vals[rowNr,colNr] 。
printf "%s%s", val, (colNr<numCols ? OFS : ORS)
}
}
}
$ awk -f tst.awk file
c1 c2 c3 c4 c5 c6 c7
111 111 222 333 111 222 777
222 444 333 111 222 333 666
333 666 444 222 333 555 555
444 777 555 777 444 666 444
777 888 777 555 555 888 333
999 999 666 666
888
uj5u.com熱心網友回復:
假設
- 整個輸出結果的(
awk)陣列將適合于記憶體 。
- 可變的列數和行數 。
一個想法包括一個(稀疏的)二維值陣列,其中陣列結構看起來像:
values[< column#>][<row#>]=<unique_cell_value>
一個使用單個awk呼叫的想法,a)需要一次性通過輸入檔案,b)不需要任何轉碼/粘貼(如果有人認真對待Cyrus的評論/建議):
awk '
開始 { fs=ofs=" " }
{ maxNF = (NF > maxNF ? NF : maxNF) # 追蹤最大列數
for (i=1; i<=NF; i ) {
if ( $i == "" ) # 忽略空單元格
繼續
for (j=1; j<=ndx[i]; j ) { # 回圈瀏覽這一列已經看到的值
if ( $i == vals[i][j]) { # 如果已經看到,那么
$i = "" # 清除當前單元格并
break # 跳出這個for/testing回圈
}
}
if ( $i != "" ) { # 如果我們得到這個var并且單元格不是空的,那么
vals[i][ ndx[i]] = $i # 在我們的陣列中存盤新值
}
}
}
END { for (j=1; j<=NR; j ) { # 回圈瀏覽所有可能的行
pfx = ""
for (i=1; i<=maxNF; i ) { # 回圈瀏覽所有可能的列
printf "%s%s", pfx, vals[i][j] # 不存在的陣列條目默認為""
pfx = OFS
}
printf "
"
}
}
' input_file
注意:陣列結構(arr[i][j])需要GNU awk,否則我們可以轉換為arr[i,j]
這就產生了:
C1 C2 C3 C4 C5 C6 C7
111 111 222 333 111 222 777
222 444 333 111 222 333 666
333 666 444 222 333 555 555
444 777 555 777 444 666 444
777 888 777 555 555 888 333
999 999 666 666
888
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/310846.html
標籤:
