1

I have many text files in a directory. I want to append/add * at the end of last line (content) of each and every text file of the directory with the extension .txt How can this be achieved in Ubuntu 20.10 in single operation?

Why I am asking this is because currently I am working on .txt and .pgn files. If I have to convert .txt to .pgn file then an *, 1/2-1/2, 1-0 or 0-1 is needed at the end of the last line, (signifying score or end of game to the machine) otherwise I will not be able to convert them to .pgn files. Also even if I convert them to .pgn files by save as, then also the file would still be incomplete and unreadable in machine binary that will be made out of it. Machine will not be able to identify it as a score or end.

5
  • 1
    sed -i '$a*' filename is just a quick way to do it. You might want to add a little bit more to your question here if your text files all have the same extension. Any file, even a config file might be read as a text file if they don't use like a SheBang line, etc as their first line. Or if they are not a binary, encrypted, etc. Everything in Linux is a file.
    – Terrance
    Feb 14, 2021 at 15:25
  • @Terrance sed -i '$a*' filename returns sed: can't read filename: No such file or directory I have edited the question as you suggested me. There are many .txt files in the same directory.
    – user1166730
    Feb 14, 2021 at 15:33
  • 1
    You need to specify which filename. I did not specify all files because I don't know what files you want to actually append this to. If they are all .txt then that will work with a loop to read through the files. I have not written an answer yet as my comment above is just a comment.
    – Terrance
    Feb 14, 2021 at 15:34
  • All right. All the files in that directory are .txt files only. There are no other types of files. I wish to add * at the end of the content (end of last line) of each of those .txt files. I do not know how to do a loop.
    – user1166730
    Feb 14, 2021 at 15:39
  • Ah. Thank you for attempting to solve this. There are spaces in file names, so I think this could not work on them.
    – user1166730
    Feb 14, 2021 at 15:44

3 Answers 3

3

This one should be able to do it to all your .txt files.

Run from the current folder that all your .txt files are in:

find . -maxdepth 1 -iname "*.txt" -print0 | xargs -L1 -0 sed -i '$a*'

That command will find all files even with spaces then append a * to the last line of all the .txt files found in that folder.

Hope this helps!

4
  • 1
    Thank you very much @Terrance. This command did the work. Now content of all the files in that directory has * at the end. Thanks. :)
    – user1166730
    Feb 14, 2021 at 16:06
  • 1
    +1 for this correct answer.
    – Raffa
    Feb 14, 2021 at 16:46
  • 1
    @Maverick This answer is correct and accepting it is the right thing since it came first and it worked for you. My answer is an addition with a different way. There are many correct ways for doing the same thing. There might be more answers added by other users in the future. Diversity is something good and healthy. :)
    – Raffa
    Feb 14, 2021 at 17:29
  • 1
    @Raffa you are very right. :) :)
    – user1166730
    Feb 14, 2021 at 17:39
3

This can do the job for smaller numbers of files (around 1000 files):

echo "*" | tee -a *.txt >/dev/null

or use this for larger numbers of files:

for f in *.txt
    do
    echo "*" >> "$f"
    done

Run the above commands from the directory containing the .txt files.

1
  • 1
    Thank you so much for posting additional answer. Today all my queries were resolved. Thank you and Terrance. :) There is no provision for accepting two different right answers for same question I think. Because when I tick the first right answer, the tick from second answer is removed and vice versa.
    – user1166730
    Feb 14, 2021 at 17:16
0

You could go a step further and use the

    files

command to help you determine which files are ASCII text.

To that end, I've made a small shell script called addstar.sh in my home directory

    file $1 | grep ": ASCII text"  | sed "s/: ASCII text.*//g" |  echo "*" >> $1

when combined with the find command, you have a solution

    find  -maxdepth 1 -mindepth 1 -name "*.txt"  -exec  ~/addstar.sh {} \;

    

the -maxdepth and -mindepth parameters keep it to a single directory.

Regards, mondotofu

P.S. don't forget to

    chmod +x ~/addstar.sh

P.P.S Bear in mind that there are many kinds of text. Here's a quick scan of files in my home directory.

$ file * | grep "text"
addstar.sh:                                                        ASCII text
agent-install.log:                                                 UTF-8 Unicode text, with CRLF, CR, LF line terminators, with escape sequences
cantcopy.log:                                                      UTF-8 Unicode text, with very long lines
conda_install_altair.log:                                          ASCII text
conda_install_altair.log2:                                         ASCII text
conda_install_altair.log2~:                                        ASCII text
conf.yaml:                                                         ASCII text
files.list:                                                        ASCII text
fun_reports.txt:                                                   ASCII text
release-notes.html:                                                HTML document, UTF-8 Unicode text
stacktrace_20200724-1656.txt:                                      ASCII text, with CRLF, LF line terminators
T480_config-backup.sh:                                             ASCII text

You may need to adapt the one-shot command where I grep only for ASCII text and see whether you need to adapt it to kind other sorts of text output.

2
  • Thank you friend. :) :)
    – user1166730
    Feb 14, 2021 at 18:12
  • 1
    Because pgn files are supposed to be ASCII text, this should work without having to rename anything.
    – mondotofu
    Feb 14, 2021 at 18:45

You must log in to answer this question.