我有一個帶有一堆序列號的文本檔案,它們應該是 16 個字符長。但有些記錄已損壞,長度為 13 個字符。我想在每條長度為 13 個字符的記錄的開頭添加 3 個零。
注意:序列號不是從行首開始,而是從每行的第 15 列開始。
我的檔案目前看起來像這樣:
1:6822:26::A: 0000000999993 ::DIS:14516E::01::: ::0529483733710:::
1:6822:26::A: 0000000999994 ::MAT:13L324::01::::: : : :
1:6822:26: :A: 0000000999995 : :CAT:P13WFB : 01: : : ::0529483697940: : :
1:6822:26: :3: 0000000000170891 : :AZDG-2 :0000009: 3 0000000000 :::::::
1:6822:26::3: 0000000000170892 ::AZDG-3:0000003999:01:0000000000::::::::
1:6822:26::3: 0000000000170893 ::AZDG-4:0000003999:01:0000000000:::::::
輸出應該是:
1:6822:26::A: 0000000000999993 ::DIS:14516E::01::::::::0529483733710::::
1:6822:26::A: 0000000000999994 ::MAT:13L324:::01::: :: :
1:6822:26: :A: 0000000000999995 : :CAT:P13WFB : 01: : : ::0529483697940: : :
1:6822:26: :3: 0000000000170891 : :AZDG-2 1:0000: 0000000000 :::::::
1:6822:26::3: 0000000000170892 ::AZDG-3:0000003999:01:0000000000::::::::
1:6822:26::3: 0000000000170893 ::AZDG-4:0000003999:01:0000000000:::::::
這是我為獲取縮短的記錄而撰寫的代碼:
#!/bin/bash
i=1
for OUTPUT in $*(cut -c15-30 file.txt)
do
if [[ ${#OUTPUT} == 13 ]]
then
echo $OUTPUT
echo $i
i=$((i 1))
fi
done
txt 檔案有超過 50,000 條記錄,所以我無法手動更改它們。
uj5u.com熱心網友回復:
這個sed單線應該可以完成這項作業:
sed 's/^\(.\{14\}\)\([0-9]\{13\}[^0-9]\)/\1000\2/' file
這假設序列號僅由十進制數字組成,并相信它們都從每行的第 15 列開始。
或者,一個awk解決方案:
awk 'BEGIN { FS=OFS=":" } length($6) == 13 { $6 = "000" $6 } 1 ' file
這僅檢查第六個欄位的長度是否為 13,并相信第六個欄位是序列號欄位。
uj5u.com熱心網友回復:
一個awk替換所有 OP 當前代碼的想法:
awk '
BEGIN { FS=OFS=":" } # set input/output field delimiter to ":"
length($6)<16 { $6=sprintf("6d",$6) } # if length of 6th field < 16 then left-pad the field with 0's to length of 16
1 # print current line
' file.txt
這會產生:
1:6822:26: :A:0000000000999993:DIS:14516E : :01: : : ::0529483733710: : :
1:6822:26: :A:0000000000999994:MAT:13L324 : :01: : : :: : : :
1:6822:26: :A:0000000000999995:CAT:P13WFB : :01: : : ::0529483697940: : :
1:6822:26: :3:0000000000170891: :AZDG-2 :0000003999:01:0000000000: : :: : : :
1:6822:26: :3:0000000000170892: :AZDG-3 :0000003999:01:0000000000: : :: : : :
1:6822:26: :3:0000000000170893: :AZDG-4 :0000003999:01:0000000000: : :: : : :
uj5u.com熱心網友回復:
我冒昧地附上一個:...
$ awk '{if(length($2)<19){$2=gensub(/^(:.:)/,"\\1000","1",$2)":"}}1' file.txt
1:6822:26: :A:0000000000999993: :DIS:14516E : :01: : : ::0529483733710: : :
1:6822:26: :A:0000000000999994: :MAT:13L324 : :01: : : :: : : :
1:6822:26: :A:0000000000999995: :CAT:P13WFB : :01: : : ::0529483697940: : :
1:6822:26: :3:0000000000170891: :AZDG-2 :0000003999:01:0000000000: : :: : : :
1:6822:26: :3:0000000000170892: :AZDG-3 :0000003999:01:0000000000: : :: : : :
1:6822:26: :3:0000000000170893: :AZDG-4 :0000003999:01:0000000000: : :: : : :
如果這不是您想要的,請使用:awk '{if(length($2)<19){$2=gensub(/^(:.:)/,"\\1000","1",$2)}}1' file.txt
uj5u.com熱心網友回復:
另一種選擇
awk -v{O,}FS=: '{$6=gensub(" ", "0", "g", sprintf("s", gensub(" ", "", "g", $6)))}1'
結果
1:6822:26: :A:0000000000999993:DIS:14516E : :01: : : ::0529483733710: : :
1:6822:26: :A:0000000000999994:MAT:13L324 : :01: : : :: : : :
1:6822:26: :A:0000000000999995:CAT:P13WFB : :01: : : ::0529483697940: : :
1:6822:26: :3:0000000000170891: :AZDG-2 :0000003999:01:0000000000: : :: : : :
1:6822:26: :3:0000000000170892: :AZDG-3 :0000003999:01:0000000000: : :: : : :
1:6822:26: :3:0000000000170893: :AZDG-4 :0000003999:01:0000000000: : :: : : :
uj5u.com熱心網友回復:
因為你的問題用bash. 作為研究物件。
# init array arr
arr=();
# read current row with field separator : from file to array arr
while IFS=":" read -r -a arr rest; do
# remove leading zeros to avoid problem with octal numbers in bash
# and then pad leading zeros
printf -v arr[5] "6d" "${arr[5]## (0)}";
# output array arr with field separator :
for i in "${arr[@]}"; do
printf '%s:' "$i";
done;
printf '\n';
done < file
輸出:
1:6822:26::A:0000000000999993::DIS:14516E::01::: ::0529483733710::: 1:6822:26::A:0000000000999994::MAT:13L324::01:::::::: 1:6822:26::A:0000000000999995::CAT:P13WFB::01::::::0529483697940::: 1:6822:26::3:0000000000170891::AZDG-2:0000003999:01:0000000000::::::: 1:6822:26::3:0000000000170892::AZDG-3:0000003999:01:0000000000::::::: 1:6822:26::3:0000000000170893::AZDG-4:0000003999:01:0000000000:::::::
選擇的工具當然是awk.
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/522986.html
標籤:重击壳Unix
