массовая замена определенных строк в файле с помощью bash

#bash

Вопрос:

У меня есть файл с именем file.txt и содержание

 $cat file.txt
this one
juice apple
orange pen
apple
rice
mouse
 

и у меня есть еще один файл под названием word.txt

 $cat word.txt
ganti
buah
bukan
 

я хочу заменить строки 1,3 и 5 в file.txt с word.txt используя bash. таким образом, конечный результат в file.txt становится:

 $cat file.txt
ganti
juice apple
buah
apple
bukan
mouse
 

как использовать bash для выполнения этой операции? Спасибо.

Комментарии:

1. Что вы пробовали до сих пор?

2. я пробовал использовать sed. cat line.txt word.txt | while read line.txt word.txt; do sed -i '${line.txt}s/.*/${word.txt}/' file.txt; done

3. но это не сработало. line.txt является ли номер строки, подлежащий замене

4. Пожалуйста, добавьте свой код к вопросу не в качестве комментария. Вероятно, вам также нужно показать содержимое line.txt и объяснить, как код должен сопоставлять данные из разных файлов. Предположительно, малайский — это просто для примера? в противном случае непонятно, почему ручка становится буа, а яблоко-нет, или как букан соотносится с рисом.

Ответ №1:

Использование ed для чтения сначала file.txt , а затем word.txt и перетасовки строк последних и, наконец, сохранения измененных file.txt :

 ed -s file.txt <<EOF
0r word.txt
4d
2m5
4d
2m6
5d
w
EOF
 

m команды перемещают строки, а d команды удаляют строки.

Ответ №2:

Мне трудно понять, что именно вы пытаетесь сделать, это тот конечный результат, который вам нужен?

 # read the 'word.txt' lines into an array called "words"
IFS=

Редактировать

Если у вас есть номера строк, которые вы хотите изменить, в файле под названием "line.txt", вы можете настроить код в соответствии с:
 IFS=


Комментарии:

1. да, это то, что я искал, большое спасибо.

Ответ №3:

Другой ed подход, с заменой процесса.

 #!/usr/bin/env bash

ed -s file.txt < <(
  printf '%sn' '1s|^|1s/.*/|' '2s|^|3s/.*/|' '3s|^|5s/.*/|' ',s|$|/|' '$a' ,p Q . ,p Q |
  ed -s word.txt
)
 

Ответ №4:

 #!/bin/bash

# the 1st argument is the word.txt file
# remaining arguments are the line numbers to replace in ascending order
# assign the patterns file to file descriptor 3
exec 3< "$1"
shift

# read the first replacement pattern
read -ru 3 replacement
current_line_number=1

# lines will be read from standard in
while read -r line; do
    # for replacement lines with a non-empty replacement str...
    if [ "$current_line_number" == "$1" -a -n "$replacement" ]; then
        echo "$replacement"
        read -ru 3 replacement # get the next pattern
        shift # get the next replacement line number
    else
        echo "$line"
    fi
    (( current_line_number   ))
done
 

Чтобы проверить

 diff expect <(./replace-lines.sh word.txt 1 3 5 < file.txt) amp;amp; echo ok
 

n' read -d '' -r -a words < word.txt

# create a 'counter'
iter=0

# for loop through the line numbers that you want to change
for i in 1 3 5
do
# the variable "from" is the line from 'file.txt' (e.g. 1, 3, or 5)
from="$(sed -n ""$i"p" file.txt)"
# the variable "to" is the index/iteration of 'word.txt' (e.g. 1, 2, or 3)
to=${words[$iter]}
# make the 'inline' substitution
sed -i "s/$from/$to/g" file.txt
# increase the 'counter' by 1
((iter ))
done

cat file.txt
ganti
juice apple
buah
apple
bukan
mouse

Редактировать

Если у вас есть номера строк, которые вы хотите изменить, в файле под названием "line.txt", вы можете настроить код в соответствии с:


Комментарии:

1. да, это то, что я искал, большое спасибо.

Ответ №3:

Другой ed подход, с заменой процесса.


Ответ №4:


Чтобы проверить


n' read -d '' -r -a words < word.txt

iter=0

while read -r line_number
do
from="$(sed -n ""$line_number"p" file.txt)"
to=${words[$iter]}
sed -i "s/$from/$to/g" file.txt
((iter ))
done < line.txt

cat file.txt
ganti
juice apple
buah
apple
bukan
mouse

Комментарии:

1. да, это то, что я искал, большое спасибо.

Ответ №3:

Другой ed подход, с заменой процесса.


Ответ №4:


Чтобы проверить


n’ read -d » -r -a words < word.txt

# create a ‘counter’
iter=0

# for loop through the line numbers that you want to change
for i in 1 3 5
do
# the variable «from» is the line from ‘file.txt’ (e.g. 1, 3, or 5)
from=»$(sed -n «»$i»p» file.txt)»
# the variable «to» is the index/iteration of ‘word.txt’ (e.g. 1, 2, or 3)
to=${words[$iter]}
# make the ‘inline’ substitution
sed -i «s/$from/$to/g» file.txt
# increase the ‘counter’ by 1
((iter ))
done

cat file.txt
ganti
juice apple
buah
apple
bukan
mouse

Редактировать

Если у вас есть номера строк, которые вы хотите изменить, в файле под названием «line.txt», вы можете настроить код в соответствии с:


Комментарии:

1. да, это то, что я искал, большое спасибо.

Ответ №3:

Другой ed подход, с заменой процесса.


Ответ №4:


Чтобы проверить