Số không điền đến 2 chữ số với sed


19

Đầu vào:

201103 1 /mnt/hdd/PUB/SOMETHING
201102 7 /mnt/hdd/PUB/SOMETH ING
201103 11 /mnt/hdd/PUB/SO METHING
201104 3 /mnt/hdd/PUB/SOMET HING
201106 1 /mnt/hdd/PUB/SOMETHI NG

Kết quả mong muốn:

201103 01 /mnt/hdd/PUB/SOMETHING
201102 07 /mnt/hdd/PUB/SOMETH ING
201103 11 /mnt/hdd/PUB/SO METHING
201104 03 /mnt/hdd/PUB/SOMET HING
201106 01 /mnt/hdd/PUB/SOMETHI NG

Làm cách nào tôi có thể thêm một 0nếu chỉ có một chữ số duy nhất, ví dụ như 1trong phần "ngày"? Tôi cần định dạng ngày này: YYYYMM DD.

Câu trả lời:


13
$ sed 's/\<[0-9]\>/0&/' ./infile
201103 01 /mnt/hdd/PUB/SOMETHING
201102 07 /mnt/hdd/PUB/SOMETH ING
201103 11 /mnt/hdd/PUB/SO METHING
201104 03 /mnt/hdd/PUB/SOMET HING
201106 01 /mnt/hdd/PUB/SOMETHI NG

Bạn có thể giải thích làm thế nào điều này hoạt động? Đây là lần đầu tiên tôi nhìn vào \<[0-9]\>cấu trúc mà tôi nghĩ là người chịu trách nhiệm khớp các chữ số đơn lẻ nhưng không chắc chắn cấu trúc này được gọi là gì. Cảm ơn.
sasuke

2
\ <có nghĩa là: bắt đầu của một 'từ' ... [0-9] có nghĩa là một chữ số từ 0 đến 9 ... \> có nghĩa là: kết thúc của một 'từ' ... từ: một mã thông báo được phân cách bằng khoảng trắng (hoặc bắt đầu / kết thúc ở đầu / cuối dòng, tương ứng với \ <và \>) ... PS. Tôi chỉ thử dấu chấm câu .. chúng cũng là dấu phân cách.
Peter.O

1
Bạn cũng có thể làm điều này mà không cần bắt các dấu ngoặc đơn: &trong chuỗi thay thế sẽ sử dụng LHS phù hợp -sed 's/\<[0-9]\>/0&/'
glenn jackman

Ồ, không biết đó <>là một ranh giới từ trong cú pháp regex shell. Nghĩ về nó, ngay cả `sed 's / \ b [0-9] \ b / 0 & /' cũng hoạt động. Cảm ơn cả hai người. :)
sasuke

@sasuke: <>là một tính năng của regex mở rộng (không phải là shell), tùy thuộc vào phiên bản nào và tùy chọn nào bạn sử dụng, sedshellcả hai có thể sử dụng regex mở rộng hoặc tiêu chuẩn ... sử dụng regex tiêu chuẩn\<\>
Peter. O


2

Đây là một cách (không phải sed) để sử dụng bash với regex mở rộng ..
Phương pháp này, cho phép phạm vi thực hiện xử lý phức tạp hơn các dòng riêng lẻ. (tức là không chỉ thay thế regex)

while IFS= read -r line ; do
    if [[ "$line" =~ ^(.+\ )([0-9]\ .+)$ ]]  
    then echo "${BASH_REMATCH[1]}0${BASH_REMATCH[2]}" 
    else echo "$line"
    fi
done <<EOF
201103 1 /mnt/hdd/PUB/SOMETHING
201102 7 /mnt/hdd/PUB/SOMETH ING
201103 11 /mnt/hdd/PUB/SO METHING
201104 3 /mnt/hdd/PUB/SOMET HING
201106 1 /mnt/hdd/PUB/SOMETHI NG
EOF

đầu ra:

201103 01 /mnt/hdd/PUB/SOMETHING
201102 07 /mnt/hdd/PUB/SOMETH ING
201103 11 /mnt/hdd/PUB/SO METHING
201104 03 /mnt/hdd/PUB/SOMET HING
201106 01 /mnt/hdd/PUB/SOMETHI NG

1

Tôi sẽ làm một cái gì đó như thế này:

sed -E 's/ ([0-9]) / 0\1 /' ./input

Điều này lấy các số cô đơn, tách chúng thành khoảng trắng với một nhóm ' ([0-9]) ', sau đó đặt chúng trở lại với 0 và đệm khoảng trắng ' 0\1 '.

Các -Etùy chọn cho phép cho các biểu thức regex hiện đại trên OSX (do đó bạn không cần phải sử dụng "\"quá thường xuyên), -rlàm điều tương tự trên hệ thống linux Tôi đã thử nghiệm.


-1
while read a b c
do 
new_format=$(printf "%02d" $b)
echo "$a $new_format $c"
done </tmp/input
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.