Trong Bash, làm cách nào để thêm một chuỗi sau mỗi dòng trong tệp?


112

Làm cách nào để thêm một chuỗi sau mỗi dòng trong tệp bằng cách sử dụng bash? Nó có thể được thực hiện bằng cách sử dụng lệnh sed, nếu vậy làm thế nào?

Câu trả lời:


188

Nếu bạn sedcho phép chỉnh sửa tại chỗ thông qua -itham số:

sed -e 's/$/string after each line/' -i filename

Nếu không, bạn phải tạo một tệp tạm thời:

typeset TMP_FILE=$( mktemp )

touch "${TMP_FILE}"
cp -p filename "${TMP_FILE}"
sed -e 's/$/string after each line/' "${TMP_FILE}" > filename

Tại sao bạn touchlại là tập tin tạm thời? Và tôi sẽ làm cho sedlệnh có điều kiện về sự thành công của cphoặc bản gốc có thể bị mất.
Tạm dừng cho đến khi có thông báo mới.

Tôi chạm vào tệp để nhanh chóng đặt tên tạm thời. Điều này có thể không cần thiết. Tôi nghĩ bạn đã đúng khi đặt lệnh sed có điều kiện đối với sự thành công của cp. Tại sao không chỉnh sửa mã để thực hiện sửa chữa đó. Tôi sẽ không phiền một chút! Trân, Tom
Tom DeGisi

Thêm một chuỗi vào trước một dòng thì sao?
Oxwivi,

10
@Oxwivi: sed -e 's/^/string after each line/' -i filename $ có nghĩa là cuối dòng. ^ có nghĩa là đầu dòng.
Tom DeGisi

Nếu tôi đang nhập vào sed, sed 's/^/string after each line/'thì có những gì tôi mong đợi (thêm vào từng dòng) nhưng sed 's/^/string after each line/'không (nó thay thế toàn bộ dòng bằng chuỗi phụ của tôi). Đưa cái gì? Có ý kiến ​​gì không @TomDeGisi?
philadams

17

Tôi thích sử dụng hơn awk. Nếu chỉ có một cột, hãy sử dụng $0, nếu không hãy thay thế nó bằng cột cuối cùng.

Một chiều,

awk '{print $0, "string to append after each line"}' file > new_file

hoặc cái này,

awk '$0=$0"string to append after each line"' file > new_file

1
Ngoài ra, để thêm số dòng (như là trong trường hợp của tôi), người ta có thể sử dụng NRbiến:awk '{print $0, NR}'
andrybak

2
@optimus Tôi đã thử phương pháp của bạn, nhưng nhận được thêm một khoảng trống cho chúng, bất kỳ ý tưởng nào về cách xóa chúng?
Adil Saju

@AdilSaju sed 's/ //g'điều này phù hợp với yêu cầu của tôi, nhưng nó sẽ loại bỏ khoảng trống trong mọi dòng, đó là tùy chọn gcho và ở mọi nơi trong một dòng.
Eklavyaa

@AdilSaju vui lòng thêm chi tiết. Tốt hơn là đặt một câu hỏi mới.
Optimus Prime

@AdilSaju awk Xóa lượt , thích {print $0"string to append after each line"}.
Culip

8

Nếu bạn có nó, tiện ích lam (laminate) có thể làm điều đó, ví dụ:

$ lam filename -s "string after each line"

4
  1. Vỏ POSIX tinh khiết và sponge:

    suffix=foobar
    while read l ; do printf '%s\n' "$l" "${suffix}" ; done < file | 
    sponge file
    
  2. xargsprintf:

    suffix=foobar
    xargs -L 1 printf "%s${suffix}\n" < file | sponge file
    
  3. Sử dụng join:

    suffix=foobar
    join file file -e "${suffix}" -o 1.1,2.99999 | sponge file
    
  4. Công cụ Shell sử dụng paste, yes, head & wc:

    suffix=foobar
    paste file <(yes "${suffix}" | head -$(wc -l < file) ) | sponge file
    

    Lưu ý rằng pastechèn một ký tự Tab trước đó $suffix.

Tất nhiên spongecó thể được thay thế bằng tệp tạm thời, sau đó thay thế mvtên tệp gốc, như với một số câu trả lời khác ...


1
Không ai trong số này thích hợp hơn sed, trừ khi nguồn lực rất hạn chế.
agc

Tôi thích giải pháp không phải sed. sedkhông cần thiết cho một công việc đơn giản như vậy.
Bruce,

1

Tôi thích hơn echo. sử dụng bash tinh khiết:

cat file | while read line; do echo ${line}$string; done

-9

Sed hơi xấu, bạn có thể làm điều đó một cách thanh lịch như vậy:

hendry@i7 tmp$ cat foo 
bar
candy
car
hendry@i7 tmp$ for i in `cat foo`; do echo ${i}bar; done
barbar
candybar
carbar

2
Không thành công đối với các tệp có nhiều dòng hơn giới hạn đối số tối đa của trình bao. Thử: cat foo | trong khi đọc a; làm echo $ {a} bar; hoàn thành hoặc một cái gì đó tương tự thay thế; nó là một sự thay thế phù hợp trong hầu hết các trường hợp.
alex

1
Nó cũng không thành công đối với các dòng có khoảng trắng trong đó.
Tạm dừng cho đến khi có thông báo mới.

1
Ơ, không, không phải đâu Dennis. giới hạn đối số tối đa của shell? Crikey bạn đang bị lãng phí.
hendry

Có nó không: $ cat foo foo bar baz alex @ armitage: ~ $ cho tôi trong cat foo; làm echo $ {i} bar; đã thực hiện foobar barbar barbar bazbar nhưng sau một số bài kiểm tra, tôi có thể sai về lập luận của mình, nhưng Dennis đã đúng
alex

3
@hendry Có, điều này không thành công đối với các dòng có khoảng trắng trong đó, chẳng hạn như echo "foo bar" | (for i in `cat`; do echo ${i}bar; done)in 2 dòng mặc dù đầu vào là 1 dòng foo bar(và catviệc đọc từ stdin thay vì tệp không tạo ra sự khác biệt cho điều này).
hyde
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.