Home > Net >  cat without line breaks: why does tr '\n' not work?
cat without line breaks: why does tr '\n' not work?

Time:07-25

I generated 1000 output files containing a single line with (mistakenly) no line break at the end, so that

cat filnename_* > outfile

generates a file with a single line. I attempted to remedy this using

cat filename_* | tr '\n' ' ' > outfile

but I get exactly the same result - a file with a single line of output. Why doesn't the latter code (which ought to add a line break for each filename_* file) accomplish what I'm trying to do?

CodePudding user response:

I think you could manually append a line break to your 1000 out files, and then cat them all later:

echo | tee -a filename_*
cat filnename_* > outfile

Edit: Change the first step to echo | tee -a filename_* as @rowboat suggested

CodePudding user response:

tr '\n' ' ' says to replace each \n with a space; you've already stated the inputs do not contain any \n so the tr does nothing and the final output is just a copy of the input

Setup:

for ((i=1;i<=5;i  ))
do
    printf 'abcd' > out${i}
done

$ cat out*
abcdabcdabcdabcdabcd

Many commands can process a file and add a \n, it just depends on how much typing you want to do, eg:

$ sed 's/$/&/' out*      # or: sed -n '/$/p' out*
abcd
abcd
abcd
abcd
abcd

$ awk '1' out*
abcd
abcd
abcd
abcd
abcd

I'm not coming up with any ideas on how to use cat to append a \n but one idea would be to use a user-defined function; assume we want to name our new function catn (cat and add \n on end):

$ type -a catn                           # verify name "catn" not currently in use
-bash: type: catn: not found

$ catn() { awk '1' "${@:--}"; }          # wrap function definition around the awk solution

$ catn out*  
abcd
abcd
abcd
abcd
abcd

CodePudding user response:

If all yours files are missing the final linebreak then you could use sed for adding it:

sed '$s/$/\
/' filnename_* > outfile

remark: I used a literal newline in the sed expression for compatibity with all sed's and all shells but you can get rid of it in a few different ways:

# GNU sed
sed '$s/$/\n/' filnename_* > outfile

# bash, zsh, etc...
sed $'$s/$/\\\n/' filnename_* > outfile

# POSIX shell
__lf__="
"
sed '$s/$/\'"$__lf__"/ filnename_* > outfile
  • Related