Я пытаюсь найти sed
команду, которую я могу вставить filename
в filename1
. Это мои два отдельных файла.
ВХОД filename
имеет:
Cindy 11 22 54
Chester 48 12 84
ВХОД filename1
имеет:
Name Class1 Class2 Class3
Lee 92 94 88
Chancy 91 85 95
Dora 99 77 96
Jefferry 84 98 90
Вот результат, который мне нужен (выход):
Name Class1 Class2 Class3
Lee 92 94 88
Chancy 91 85 95
Dora 99 77 96
Cindy 11 22 54
Chester 48 12 84
Jefferry 84 98 90
Если мне нужно что-то прояснить, дайте мне знать. По сути, Синди и Честер должны быть прямо между Дорой и Джефферри.
решение1
Чтобы добавить все строки из filename
в filename1
с помощью sed
команды, можно сделать следующее:
sed r filename1 filename
Однако обратите внимание, что результат будет немного отличаться от результата, указанного в вашем вопросе, а именно:
Name Class1 Class2 Class3
Lee 92 94 88
Chancy 91 85 95
Dora 99 77 96
Jefferry 84 98 90
Cindy 11 22 54
Chester 48 12 84
Редактировать
Дополнительная sed
информация, полезная для этого вопроса:
Добавить
filename
после 4-й строкиfilename1
:sed '4 r filename' filename1
Добавить
filename
после строки, которая начинается с «Дора» вfilename1
:sed '/^Dora/ r filename' filename1
Чтобы добавить
filename
после 4-й строки и удалить все пустые строкиfilename1
:sed '/^$/d;4 r filename' filename1
решение2
Если я правильно помню, никакого порядка быть не должно.
В таком случае:
$ cat file2 file1 | column -t
Name Class1 Class2 Class3
Lee 92 94 88
Chancy 91 85 95
Dora 99 77 96
Jefferry 84 98 90
Cindy 11 22 54
Chester 48 12 84
решение3
Если вы это сделаете:
sed r file1 file2
...тогда sed
попытается и не сможет добавить r
файл ead с именем файла нулевой длины к каждой входной строке обоих именованных входных файловfile1
иfile2
. Эта команда по сути ничем не отличается от:
sed '' file1 file2
...за исключением того, что r
он медленнее.
Это то, что я имею в виду:
seq 1 5 > file1
seq 6 10 > file2
strace sed r file[12]
...
write("1\n", 21) = 2
open("", O_RDONLY) = -1 ENOENT (No such file or directory)
write("2\n", 21) = 2
open("", O_RDONLY) = -1 ENOENT (No such file or directory)
write("3\n", 21) = 2
open("", O_RDONLY) = -1 ENOENT (No such file or directory)
write("4\n", 21) = 2
open("", O_RDONLY) = -1 ENOENT (No such file or directory)
write("5\n", 21) = 2
open("", O_RDONLY) = -1 ENOENT (No such file or directory)
read(3, "", 4096) = 0
close(3) = 0
open("file2", RDONLY) = 3
write("6\n", 21) = 2
open("", O_RDONLY) = -1 ENOENT (No such file or directory)
write("7\n", 21) = 2
...
Увидеть open("" ...)
неудачу сENOENT
после каждой выписанной строки? Это пустая r
команда ead sed
запускается. Вы не замечаете сбоев, потому что sed
специфицировано, чтобы не жаловаться на несуществующий r
файл ead, указанный в его скрипте, а скорее продолжать работать так, как будто ничего не произошло, когда он пытается r
прочитать его.
И может быть этовыглядиткак будто это работает, потому что вы просто хотите добавить файл в конец другого - чтобы объединить cat
два файла - что sed
происходит по умолчанию, когда два входных файла названы - он читает первый, а затем следующий. Но если бы r
команда ead действительно работала, то названный r
файл ead был бы добавлен полностью ккаждыйлинейный вход.
Так:
seq 3 > file
printf %s\\n a b c |
sed r\ file
a
1
2
3
b
1
2
3
c
1
2
3
Чтобы добавить содержимое одного файла в другой, вы можете сделать следующее:
cat < file2 >> file1
Чтобы добавить данные только после определенной точки ввода, у вас есть несколько вариантов. sed
Среди них:
sed -e '/match/{r file2' -e:n -e 'n;bn' -e \} file1
...который должен работать практически с любым sed
.
Или, если у вас POSIX sed
:
{ sed /match/q; cat file2 -; } < file1
...что должно быть гораздо эффективнее.
Оба метода гарантируют, что содержимоеfile2
читается только r
один раз и только сразу после первого появления match
словаfile1
.
Другой способ может выглядеть так:
cat file2 | sed /match/r\ /dev/fd/0 file1
...который будет считывать файл нулевой длины после каждого совпадения, следующего за первым...