Shell-Script

什麼命令將輸入製表符分隔的文本文件並將每行剪切為 80 個字元?

  • December 25, 2014

我有(有時)製表符分隔數據的多行文本文件。我想輸出文件,以便我可以瀏覽它 - 所以我只想看到每行的前 80 個字元(我設計的文本文件將重要的東西放在每行的首位)。

我以為我可以使用 cat 讀取文件的每一行,並將每一行發送到管道中的下一個命令:

cat tabfile | cut -c -80

但這似乎被打破了。我試著到處亂跑,grep 似乎可以工作 - 但後來我發現,不,它沒有(不是文件中的每一行都有 80 多個字元) - 似乎選項卡被剪切計為單個字元。

我試過:

cat tabfile | tr \t \040 | cut -c -80

即使這會通過消除空白可讀性來破壞我的數據。但這沒有用。也沒有:

cat tabfile | tr \011 \040 | cut -c -80

也許我用錯了tr?我之前遇到過 tr 的問題,想要刪除多個空格(似乎我在這台機器上可以訪問的 tr 版本有一個 -s 選項來壓縮多個字元 - 我可能需要更多地使用它)

我敢肯定,如果我搞砸了,我可以使用 perl、awk 或 sed 或其他東西來做到這一點。

但是,我想要一個使用(POSIX?)正常命令的解決方案,以便它盡可能便攜。如果我最終使用 tr,我可能最終會嘗試將製表符轉換為字元,也許進行計算,減少計算,然後將這些字元轉換回輸出的製表符。

它不需要是單行/直接在命令行上輸入 - 腳本就可以了。


有關選項卡文件的更多資訊:

我使用製表符來分隔欄位,因為有一天我可能想將數據導入其他程序。所以我傾向於在內容之間只有一個標籤。但我也使用製表符將內容與垂直列對齊,以幫助查看純文字文件時的可讀性。這意味著對於某些文本,我用空格填充內容的末尾,直到我到達選項卡的工作位置,以便將下一個欄位與其上方和下方的欄位對齊。

DarkTurquoise #00CED1 海洋、天空、划艇自然
MediumSpringGreen #00FA9A 對樹木有用 魔法 
青檸 #00FF00 僅用於春雞和水果$

我認為您正在尋找expand和/或unexpand. 看來您正在嘗試確保\tab 寬度計為 8 個字元而不是單個字元。fold也會這樣做,但它會將其輸入包裝到下一行而不是截斷它。我想你想要:

expand < input | cut -c -80

expand並且unexpand都是POSIX 指定的:

  • expand實用程序應將文件或標準輸入寫入標準輸出,並將\tab 字元替換為填充到下一個製表位所需的一個或多個空格字元。任何退格字元都應複製到輸出中,並導致製表位計算的列位置計數減少;列位置計數不應減少到零以下。

很簡單。所以,這裡看看它的作用:

unset c i; set --;                                                             
until [ "$((i+=1))" -gt 10 ]; do set -- "$@" "$i" "$i"; done                      
for c in 'tr \\t \ ' expand;  do eval '                                           
   { printf "%*s\t" "$@"; echo; } | 
     tee /dev/fd/2 |'"$c"'| { 
     tee /dev/fd/3 | wc -c >&2; } 3>&1 |
     tee /dev/fd/2 | cut -c -80'
done

until頂部的循環獲取一組數據,例如…

1 1 2 2 3 3 ...

printf帶有%*sarg 填充標誌,因此對於集合中的每一個,printf都將填充與參數數量一樣多的空格。每一個它都附加一個\tab 字元。

所有tees 都用於顯示每個過濾器在應用時的效果。

效果如下:

1        2        3        4        5        6        7        8                9               10
1  2   3    4     5      6       7        8         9         10 
1  2   3    4     5      6       7        8         9         10 
66
1        2        3        4        5        6        7        8                9               10
1        2        3        4        5        6        7        8                9               10 
1        2        3        4        5        6        7        8                
105

這些行排成兩組,例如…

  1. 的輸出printf ...; echo
  2. tr ...或的輸出expand
  3. 的輸出cut
  4. 的輸出wc

前四行是tr過濾器的結果,其中每個\tab 都轉換為一個空格

和底部四個expand鏈條的結果。

引用自:https://unix.stackexchange.com/questions/175852