How do I append text to the beginning and end of multiple text files in Bash?
Solution 1
To prepend text to a file you can use (with the GNU implementation of sed
):
sed -i '1i some string' file
Appending text is as simple as
echo 'Some other string' >> file
The last thing to do is to put that into a loop which iterates over all the files you intend to edit:
for file in *.txt; do
sed -i '1i Some string' "$file" &&
echo 'Some other string' >> "$file"
done
Solution 2
Fully POSIX compliant command, using ex
:
for f in *.txt; do printf '%s\n' 0a 'var language = {' . '$a' '};' . x | ex "$f"; done
If you run the printf
portion of the command by itself, you will see the exact editing commands that it is passing to ex
:
0a
var language = {
.
$a
};
.
x
0a
means "Append text after line 0" (in other words, before the first line). The next line is the literal text to "append" after line 0. The period (.
) on a line by itself ends the text to be appended.
$a
means to append text after the last line of the file.
x
means to save the changes and exit.
Solution 3
Also has the right to be (with results in .out
files):
find . -name '*.txt' -exec sh -c '(echo HEAD;cat {};echo FOOT) > {}.out' \;
Another, more elaborated variant - source files replaced with result:
find . -name '*.txt' -exec sh -c '(echo HEAD;cat {};echo FOOT) > {}.tmp && mv {}.tmp {}' \; -print
Solution 4
Here's a way to do it in Perl:
for f in ./*txt; do
perl -lpe 'BEGIN{print "First string"}END{print "Last string"}' "$f" > foo &&
mv foo "$f";
done
Solution 5
Try using ex
:
ex -s +'bufdo!1s/^/HEAD/|$s/$/TAIL/' -cxa *.foo
where commands are:
-
bufdo!
executes below commands for each opened buffer/file (note: it's not POSIX) -
1s/^/HEAD/
- insertsHEAD
text into the first line at the beginning of the line -
$s/$/TAIL/
- appendsTAIL
text on the last line at the end of the line
and arguments are:
-
-s
- silent/quick mode -
-cxa
- save all opened buffers/files and quit -
*.foo
- all files in the current directory (*
) withfoo
extension, use**/*.foo
for recursivity (after enabling globstar:shopt -s globstar
)
ADAM
Updated on September 18, 2022Comments
-
ADAM over 1 year
I have a directory full of text files. My goal is to append text to the beginning and end of all of them. The text that goes at the beginning and end is the same for each file.
Based on code I got from the web, this is the code for appending to the beginning of the file:
echo -e 'var language = {\n$(cat $BASEDIR/Translations/Javascript/*.txt)' > $BASEDIR/Translations/Javascript/*.txt
This is the code for appending to the end of the file. The goal is to add the text
};
at the end of each file:echo "};" >> $BASEDIR/Translations/Javascript/*.txt
The examples I drew from were for acting on individual files. I thought I'd try acting on multiple files using the wildcard,
*.txt
.I might be making other mistakes as well. In any case, how do I append text to the beginning and end of multiple files?
-
user1730706 about 8 yearsnote bufdo is not POSIX pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html
-
Oleh Prypin almost 8 years@StéphaneChazelas adding
-i
instead of this file substitution does not work, it just prints to stdout. -
Stéphane Chazelas almost 8 years@OlehPrypin, indeed your right. Comment deleted.
-
Wildcard over 7 years@StevenPenny is right. I use POSIX specified features only, personally, for scripted edits.
-
Walf over 2 yearsPerhaps explain the process of this (typically) terse program.