2017-09-27 71 views
0

我尋找一種方法,其中追加0以多條線的端部在一個文件中,如果他們是在長度上小於66個字符使總線路長度等於66追加0以在UNIX/bash的一個文件,如果該行是小於一個固定的長度

這裏的文件格式的一個例子(...表示前述56個字符):

$cat file1 
...1234567891 
...123456 
... 
...12345678 

理想格式:

...1234567891 
...1234560000 
...0000000000 
...1234567800 
+3

兩個問題:爲什麼你想這樣的事情?你到目前爲止嘗試過什麼? –

+0

Hi Hubert,它正在運行一個批處理套件(需要固定長度的文件),而且我正在使用的文件是在另一個shell腳本的後面生成的,我目前無法訪問該腳本進行編輯。 我已經看過並設法通過grep'。\ {66 \}'來抓住非66長度的字符,所以加快了速度但追加了零,它將循環添加到了我正在努力掙扎的零點從腳本/ unix背景:)。 我不確定是否有快速的方法在bash/unix中執行它,而不必創建另一個腳本來處理此問題:) 謝謝, Jordan。 –

回答

2

GNU AWK溶液:

$ awk '{s=$0; while(length(s)<66) s=s "0"; print s}' file1 

或甚至更短:

$ awk '{while(length<66) $0=$0 "0"}1' file1 

與設置輸入:

$ awk '{while(length<66) $0=$0 "0"}1' file1 
...123456789100000000000000000000000000000000000000000000000000000 
...123456000000000000000000000000000000000000000000000000000000000 
...000000000000000000000000000000000000000000000000000000000000000 
000000000000000000000000000000000000000000000000000000000000000000 
...123456780000000000000000000000000000000000000000000000000000000 
+0

謝謝:) 鑑於我可能需要更多的練習和提高技巧,你有沒有推薦的資源,你已經用來學習這個東西? 約旦。 –

+1

當然:https://www.gnu.org/software/gawk/manual/適合初學者。 –

+1

和谷歌的「有效的AWK編程」阿諾德羅賓斯 –

2

這裏的一個的Python需要一行代碼。

測試數據

$ cat test 
12345678aaaaaaaaaaaaaaaaaaaaaaa 
123 

33333333 

Python 3中

$ python3 -c 'for l in open("test"):print(l.rstrip().ljust(66,"0"))' 
12345678aaaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000 
123000000000000000000000000000000000000000000000000000000000000000 
000000000000000000000000000000000000000000000000000000000000000000 
333333330000000000000000000000000000000000000000000000000000000000 

的Python 2

$ python -c 'for l in open("test"):print l.rstrip().ljust(66,"0")' 
12345678aaaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000 
123000000000000000000000000000000000000000000000000000000000000000 
000000000000000000000000000000000000000000000000000000000000000000 
333333330000000000000000000000000000000000000000000000000000000000 

爲了改變所述實際文件,直接輸出到一個臨時文件,並覆蓋原始到底:

$ python ... > newfile && mv newfile test 
1

僞代碼:

read line by line 
    while (line.length < characterNum + prefixLength) 
     line += '0'; 
    add the line to dynamic array 
make a new file with the same name (it will replace the previous one) 
write data from array to the new file 

characterNum是所需的字符數,在你的情況66,prefixLength是3你的情況(「...」)

而不是使用動態數組,你可以在while循環之後立即寫入一個新文件(使用不同的名稱),這將節省空間。

5

awk中溶液:

示例文件input.txt

ghWuec]UGaEjxQRN4qUe3uyhNmBszZeJq]0A5hZJiI[fQ[8anRKnpoLXWBwfFt300S 
0jmyMPlQbSpFf[ZNdQvR]BwuYxgW6zkBYRPC1PwJEowd7[MmeiWp8Pienu1F32 
G]nGbsTdvO24e7Ts5cLRIaYy[zOcUHau5Q7slRYmkcx2LTNR46QE]gs7vKPj 
Zxr6HwG15YyYZnDvRDibjOKOlpacrU5oZTWhBixY23]yWfbHe4i6ztME 

的工作:

awk '{ if(length<66) printf "%s%0*d\n",$0,66-length,0; else print }' input.txt 

輸出:

ghWuec]UGaEjxQRN4qUe3uyhNmBszZeJq]0A5hZJiI[fQ[8anRKnpoLXWBwfFt300S 
0jmyMPlQbSpFf[ZNdQvR]BwuYxgW6zkBYRPC1PwJEowd7[MmeiWp8Pienu1F320000 
G]nGbsTdvO24e7Ts5cLRIaYy[zOcUHau5Q7slRYmkcx2LTNR46QE]gs7vKPj000000 
Zxr6HwG15YyYZnDvRDibjOKOlpacrU5oZTWhBixY23]yWfbHe4i6ztME0000000000 

同樣可以縮短爲:

awk 'length<66{ printf "%s%0*d\n",$0,66-length,0;next }1' input.txt 
+1

非常聰明的方法來做到這一點。 – CWLiu

+0

@CWLiu,謝謝 – RomanPerekhrest

+1

這是最好的,速度快10倍++ –

1
awk '{printf $0; for(i=66; i>length; i--){printf "0"} printf "\n"}' file 

輸入:

1234567891 
123456 
123 
12345678 

輸出:

123456789100000000000000000000000000000000000000000000000000000000 
123456000000000000000000000000000000000000000000000000000000000000 
123000000000000000000000000000000000000000000000000000000000000000 
123456780000000000000000000000000000000000000000000000000000000000 
1

能否請您嘗試以下awk的解決方案也是如此,它不會有任何循環。

awk '{$0=sprintf("%066d",$0);match($0,/0[^(1-9)]*/);print substr($0,RLENGTH+1)substr($0,RSTART,RLENGTH)}' Input_file 

添加的解非一個襯片的形式現在也。

awk '{ 
$0=sprintf("%066d",$0); 
match($0,/0[^(1-9)]*/); 
print substr($0,RLENGTH+1)substr($0,RSTART,RLENGTH) 
} 
' Input_file 

比方說,下面是INPUT_FILE:

1234567891 
123456 
12345678 

然後運行的代碼輸出後將如下。

123456789100000000000000000000000000000000000000000000000000000000 
123456000000000000000000000000000000000000000000000000000000000000 
123456780000000000000000000000000000000000000000000000000000000000 

說明:

awk '{ 
$0=sprintf("%066d",$0);##Re-phrasing current line by adding necessary zeros in front of each line if its length is lesser than 66, %066d will take care of length. 
match($0,/0[^(1-9)]*/);##using match for matching regex where it will match from first zero to till a non-zero value comes, so basically it collects all added 0s. 
print substr($0,RLENGTH+1)substr($0,RSTART,RLENGTH)##Now printing the substring of 1st from starting of RLENGTH and another substring which will print from RSTART to RLENGTH, now important thing here is what are RLENGTH and RSTART, these are awk out of the box variables which will be set when a regex match is found from match where RSTART re-presents the first index number of matched regex and RLENGTH re-presents the length of matched regex. 
} 
' Input_file ## Mentioning the Input_file name here. 
+1

你能顯示輸出並解釋腳本是如何工作的嗎? – jas

+0

@jas,對不起忙,正要添加解釋。我剛添加它,請讓我知道是否有任何疑問/投訴相同。謝謝。 – RavinderSingh13

+0

此外,我不知道是否有可能,但以一個或多個'0'開始的輸入行不會將這些零維持在行的前面。 – jas

0

perl

$ # change 13 to whatever length is needed 
$ perl -lne 'print $_ . "0" x (13-length)' ip.txt 
...1234567891 
...1234560000 
...0000000000 
...1234567800 
  • $_包含不具有(由於-l選項)
  • 換行符當前行內容
  • .將串聯的兩個字符串
  • x是重複操作符,在這裏它會添加許多使線長度等於13(線大於13將不會受到影響)
  • 對於就地編輯所需0 S,使用perl -i -lne
0

在純bash的

printf -v A '0%.s0' {1..66};while read B;do B=$B$A;printf '%.66s\n' $B;done<infile 
相關問題