2017-06-19 79 views
0

我有價值觀這樣一個文本文件:轉換由` N`分離的垂直的長方形,水平

a b 
c d 
e f 
g h 

i j 
k l 
m n 
o p 

q r 
s t 
u v 
w x 

我想轉換由\n分離水平的像這樣的垂直線:

a c e g 
b d f h 

i k m o 
j l n p 

q s u w 
r t v x 

我已經試過這樣:

WRD=$(head -n 1 a.txt | wc -w); 
for((i=1; i<=$WRD; i++)); do 
    awk '{print $'$i'}' a.txt | tr '\n' ' '; echo; 
done > "sa.txt" 

但輸出中看起來是這樣的:

a c e g i k m o q s u w 
b d f h j l n p r t v x 

如何編輯它以輸出我想要的?

回答

2

擊:

while read -r line1; do if [[ -z $line1 ]]; then echo; continue; fi; read -r line2; echo "$line1 $line2"; done < file 

並與縮進:

while read -r line1; do 
    if [[ -z $line1 ]]; then 
    echo 
    continue 
    fi 
    read -r line2 
    echo "$line1 $line2" 
done < file 

輸出:

 
a b c d 
e f g h 

i j k l 
m n o p 

q r s t 
u v w x 
+1

不妨'讀一致性-r line2' ...':)' –

+0

@ DavidC.Rankin:謝謝。我已經更新了我的答案。 – Cyrus

+1

這不會產生預期的輸出,它只是合併線對而不是轉置線。 –

1

不知道你的數據將變得更加複雜,但這應該讓你開始:

awk 'NF{col1 = col1 (col1?FS:"") $1;col2 = col2 (col2?FS:"") $2;next}{print col1 RS col2;col1=col2=""}END{print col1 RS col2}' input_file 

我們用NF讓我們知道,包含數據和他們相應的存儲線。

END是必需的,因爲最後一個條目後沒有附加行。

1
  1. sed使用和paste

    sed '/^$/p' inputfile | paste -d ' ' - - 
    

    輸出:

    a b c d 
    e f g h 
    
    i j k l 
    m n o p 
    
    q r s t 
    u v w x 
    

    注意上面可能不符合規格,因爲它只有 的矩形已經偶數作品2X ň兩側(即2x4 轉置爲4x2)。 OTOH Cyrus'和grail's 答案在不規則矩形上也失敗,即如果進給grep -v '[gx]' inputfile

  2. 更一般的修復,(工作在的任何矩形和變化的大小),採用csplitdatamash

    # Create a more irregular input file: 
    grep -v '[gx]' inputfile | tee vlines3 
    

    輸出:

    a b 
    c d 
    e f 
    
    i j 
    k l 
    m n 
    o p 
    
    q r 
    s t 
    u v 
    

    代碼:

    x=`mktemp -u` 
    csplit -f $x --suppress-matched -s vlines3 '/^$/' '{*}' 
    for f in ${x}* ; do 
        datamash -W -t' ' transpose < $f 
        echo 
        rm $f 
    done | head -n -1 
    

    輸出:

    a c e 
    b d f 
    
    i k m o 
    j l n p 
    
    q s u 
    r t v 
    
2

嘗試:該解決方案也將超過2場,(我正在考慮在這裏的唯一的事情是你沒有任何空字段)工作。

awk '/^$/{for(j=1;j<=val;j++){print A[j];delete A[j];};print}{for(i=1;i<=NF;i++){;A[i]=A[i]?A[i] FS $i:$i};val=NF} END{for(j in A){print A[j]}}' Input_file 

上面一個內膽採用的解釋:

awk '/^$/{        ####Checking for a condition where a line is NULL, if yes then perform following. 
       for(j=1;j<=val;j++){  ####starting a for loop from variable i value from 1 to till variable val value. 
       print A[j];    ####printing array A value with index j. 
       delete A[j];    ####deleting array A value with index j. 
            }; 
       print      ####Print the NULL value which is new line. 
     } 
     { 
       for(i=1;i<=NF;i++){;  ####Starting a loop from i value from 1 to till NF value, where NF is number of fields in a line. 
       A[i]=A[i]?A[i] FS $i:$i ####creating an array A whose index will be number of fields and it will concatenate in its own value. 
            }; 
       val=NF     ####creating a variable named val whose value is equal to NF value. 
     } 
    END {        ####Starting END section here too. 
       for(j in A){    ####Starting a loop here which will loop through the array A. 
       print A[j]    ####Printing the array A value with index j. 
          } 
     } 
    ' Input_file       ####Mentioning the Input_file here. 
3
$ awk -v RS= '{ 
    for (i=1;i<=2;i++) { 
     for (j=i;j<=NF;j+=2) { 
      printf "%s%s", $j, (j<(NF+i-2)?OFS:ORS) 
     } 
    } 
    print "" 
}' file 
a c e g 
b d f h 

i k m o 
j l n p 

q s u w 
r t v x 
+1

由於它處理不同大小的矩形,並且比[我自己的基於工具的通用答案](https://stackoverflow.com/a/44623241/6136214)更清晰,所以它比其他'awk'答案更通用。 – agc