J'ai créé deux files:
echo -e "1\n2\n3\n4\n5" > 123.txt echo -e "a\nb\nc\nd\ne" > abc.txt
Je veux get le file 123.txt
avec le contenu suivant:
1 2 3 b c d 4 5
Donc, en d'autres termes, insérez les lignes avec des nombres de 2 à 4 du file abc.txt
dans le file 123.txt
après la troisième ligne.
J'ai examiné les nombreuses questions similaires ici, mais je n'ai pas trouvé de réponse appropriée. Néanless j'ai eu les lignes:
sed -n '2,4p' abc.txt
et mettre du text dans le file après la troisième ligne:
sed -i '3a\mytext' 123.txt
Comment faire cela en utilisant la command précédente stdout ou / et une command unique sed
/ awk
?
Si votre système possède la version GNU de sed
, vous pouvez utiliser la command GNU extension r
:
r filename As a GNU extension, this command accepts two addresses. Queue the contents of filename to be read and inserted into the output stream at the end of the current cycle, or when the next input line is read. Note that if filename cannot be read, it is treated as if it were an empty file, without any error indication. As a GNU sed extension, the special value /dev/stdin is supported for the file name, which reads the contents of the standard input.
Par exemple,
$ sed '3r /dev/stdin' 123.txt < <(sed -n '2,4p' abc.txt) 1 2 3 b c d 4 5
En utilisant awk
et sed
:
$ awk 'FNR==3{print;system("sed -n '2,4p' abc.txt");next};1' 123.txt 1 2 3 b c d 4 5
Avec sed
, vous pouvez utiliser la command r
pour insert un file entier. Pour insert une partie d'un file, extrayez cette partie et envoyez-la en input à sed
. Vous pouvez utiliser sed
pour faire l'extraction aussi.
sed -n '2,4p' abc.txt | sed -i '3r /dev/stdin' 123.txt
Avec awk
, vous pouvez lire un file et passer à un autre file au milieu.
awk <123.txt >123.txt.new ' 1 # print the input line NR==3 { # after line 3 of 123.txt, … while (getline < "abc.txt") { ++inner_NR; if (inner_NR >= 2) print; # start printing at line 2 from abc.txt if (inner_NR == 4) break; # stop after line 4 } } ' && mv 123.txt.new 123.txt
Vous pouvez également utiliser la head
et la tail
pour extraire les parties des files que vous souhaitez combiner.
head -n 3 <123.txt >123.txt.new && <abc.txt tail -n +2 | head -n 3 >>123.txt.new && tail -n +4 123.txt >>123.txt.new && mv 123.txt.new 123.txt
Vous pouvez combiner l'approche head
+ tail
avec sed
. Pour les files volumineux, il est probable que ce soit le plus rapide.
<abc.txt tail -n +2 | head -n 3 | sed -i '3r /dev/stdin' 123.txt
Notez que toutes ces approches écrivent dans un file temporaire qui est déplacé vers 123.txt
(même les approches utilisant sed -i
, parce que c'est ce que sed -i
fait sous le capot).
Modification en place à l'aide de ed
et sed
(à l'invite bash):
ed -s 123.txt<<<$'3r !sed -n "2,4p" abc.txt\nw'