Adding tab/new line at the end of each line of a file

Hello Everyone,

I need a help from experts of this community regarding one of the issue that I am facing with shell scripting.

My requirement is to append char's at the end of each line of a file. The char that will be appended is variable and will be passed through command line.
The script that I have written append almost all char but I am facing a problem with appending \t or \n when using the variable concept. However, if I hardcode \t and \n in the scripts , its working fine.

The sample file (TESTDATA.txt) that I have created is as shown below :

137798|Sourav_Das|100
127798|S_Das|101
117798|S.Das|1

and the script (SampleScript.sh) that I am using

#!/bin/ksh
#================================#
# Script to change the # 
# delimiter of any file and #
# also zip the file #
#================================#
NOW=`date '+%Y%m%d%H%M'`
NOW_DATE=`date '+%Y%m%d'`
RSUFFIX=$1
echo "==============================="
echo "$NOW"
echo "$RSUFFIX"
echo "===================="
rm TEMP1.txt
rm TEMP2.txt
touch TEMP1.txt
touch TEMP2.txt
echo "$RSUFFIX" 
##======== This doesn't work =============================
awk '{print $0 "$RSUFFIX"}' TESTDATA.txt > TEMP1.txt
##======== This works =============================
awk '{print $0 "\t\t"}' TESTDATA.txt > TEMP2.txt

The Comand line arguments for appending TAB is :

$ ./SampleScript.sh '\\t'

Can anyone of you please help me resolving this issue ?

Thanks in advance..
Sourav

you dont put shell variables inside of awk programs, at least not like that. they're different and separate things. you can pass variables to awk like this: awk -v "rsuffix=$RSUFFIX" and then use it as rsuffix .

Thanks for the reply... I tried assigning the shell variable to an awk variable and used the same in the awk command but this didn't work.\

I used

nawk -v rsuffix=$RSUFFIX 'BEGIN { print rsuffix }'

and then

awk '{print $0 rsuffix}' TESTDATA.txt > TEMP1.txt

What output did you get? Also, quote your expansions, "$RSUFFIX".

Thanks for your reply ..
Eventhough I used "$RSUFFIX" , I am not seeing any change in my output i.e. no char are appended to the last line of each record.

Below is my current code and I am executing the following , from the command line ( ./SampleScript.sh '\\t' )

SampleScript.sh ->

#!/bin/ksh
#================================#
# Script to change the #
# delimiter of any file and #
# also zip the file #
#================================#
NOW=`date '+%Y%m%d%H%M'`
NOW_DATE=`date '+%Y%m%d'`
RSUFFIX=$1
echo "==============================="
echo "$NOW"
echo "$RSUFFIX"
echo "===================="
rm TEMP1.txt
rm TEMP2.txt
touch TEMP1.txt
touch TEMP2.txt
echo "$RSUFFIX"
nawk -v rsuffix="$RSUFFIX" 'BEGIN { print rsuffix }'
##======== This doesn't work =============================
 awk '{print $0 rsuffix}' TESTDATA.txt > TEMP1.txt
##======== This works =============================
 awk '{print $0 "\t\t"}' TESTDATA.txt > TEMP2.txt

My expected Result is

137798|Sourav_Das|100<one tab>     
127798|S_Das|101<one tab>
117798|S.Das|1<one tab>

The technique should work fine.

x='\t'
awk -v x="$x" 'BEGIN { printf "%s", x }' | od -c
0000000  \t
0000001

Also, if you are already single-quoting, there's no need to double the backslash. Doing so yields two characters, a literal backslash followed by the letter tee, instead of the escape sequence that produces a single tab character.

x='\\t'
awk -v x="$x" 'BEGIN { printf "%s", x }' | od -c
0000000   \   t
0000002

Regards,
Alister

Alister,
Thanks for your reply but I am unable to correlate your solution with my requirement.. Can you please explain as how I will incorporate your solution to my requirement?

Regards,
Sourav

How are you passing the tab to your script? By quoting the corresponding escape sequence?

EDIT: OK I saw the post now. Sorry.

Call the script either with \\t or '\t' or "\t".

I don't have any reservations of using awk. If my requirement of adding char to end of line is acheived by some other means , I am ok with it

---------- Post updated at 10:47 AM ---------- Previous update was at 10:43 AM ----------

@Sinari : I have tested with the options that you have suggested but nothing works.

Are you sure nothing works? How do you check that the tab is inserted? They're very very hard to see at the end of a line.... :confused:

If you see , the script , I have two lines

##======== This doesn't work =============================
 awk '{print $0 rsuffix}' TESTDATA.txt > TEMP1.txt
##======== This works =============================
 awk '{print $0 "\t\t"}' TESTDATA.txt > TEMP2.txt

In the second line , I have hardcoded the tab and I can see the results in TEMP2.txt . Ideally , if the solution worked , then TEMP1.txt and TEMP2.txt should have the same data and structure

awk '$0=$0' ORS='\t\t\n' TESTDATA.txt > TEMP2.txt

vgersh99,
Thanks for your response. The command line appened two tabs at the end of each line. Can you please explain as how the statement works?

Also, the \t\t that you have hardcoded will be parameterized in my case. Can I replace \t\t using a parameter that I will be passing through command line?

Sorry to insult your intelligence. If you invoke your script with '\t' it should perform as so:

$ echo 'Hello World' >input
$ awk '{print $0 "\t\t"}' input | cat -e
Hello World             $
$ RSUFFIX="\t"
$ echo "$RSUFFIX"
\t
$ awk -v "rsuffix=$RSUFFIX" '{print $0 rsuffix}' input | cat -e
Hello World     $

Assigning $0=$0 can be made even shorter

$ awk 1 ORS="$RSUFFIX\n" input | cat -e
Hello World     $

In your script, rsuffix is empty, and so I don't expect it to output a <TAB> char. Try to assign sth. to it first, like rsuffix="\t" if your awk allows for that.

man awk yields:

       ORS         The output record separator, by default a newline.
#!/bin/ksh
ors='\t\t\n'

awk '$0=$0' ORS="${ors}" TESTDATA.txt > TEMP2.txt
1 Like

Thanks vgersh99 .. It worked ... Thanks a lot ..

---------- Post updated at 03:54 PM ---------- Previous update was at 12:12 PM ----------

Need another help. Is there a way to replace the delimiter of a file to tab ? The existing delimiter is pipe(|).

The type of delimiter i.e. tab or colon or semi-colon will be passed as an argument.

I am able to replace all but not the tab.

awk '$1=$1' FS='|' OFS='\t' ORS="${rsuffix}\n" input
1 Like
#!/bin/ksh
ofs='\t'
ors='\t\t\n'  

awk '$0=$0' OFS="${ofs}" ORS="${ors}" TESTDATA.txt > TEMP2.txt

@neutronscott : Thanks for your solution. It worked.
@vgersh99 : Its not working. May be because you are not mentioning the existing fileseperator in the script