How to replace \n and \t with new lines and tabs respectively with one command?

I have a file name test.sh and I want to replace every \n and \t escape character with their actual newline and tab characters at the same time.

cat test.sh

Maria\nJimenez
Jose\tBaez
Lindo\nGarcia
Luis\tOvalle
Placido\nRuiz

The result output should be something like this:

Maria
Jimenez
Jose     Baez
Lindo
Garcia
Luis     Ovalle
Placido
Ruiz

I tried the following command:

awk '{gsub(/\\n/,"\n")}1' | awk '{gsub(/\\t/,"\t")}1' test.sh 

But it doesn't replace both at the same time. Can I do this task with only one command?

it doesn't matter if the solution involves the use of sed, perl, tr or any other method.

Upvotes: 1

Views: 3032

Answers (4)

anubhava
anubhava

Reputation: 785156

printf '%b can interpret escape sequence so you can do just feed the file content to a printf command:

printf '%b\n' "$(<file)"

Maria
Jimenez
Jose    Baez
Lindo
Garcia
Luis    Ovalle
Placido
Ruiz

To save output back in file use:

printf '%b\n' "$(<file)" > file

%bexpands all backslash escape sequences not just \t or \n. For example it will also expand \f (form feed) or \r (carriage return). Check help printf or help echo for more details.

Upvotes: 1

Thomas Dickey
Thomas Dickey

Reputation: 54515

The question's at the same time could be taken literally (though none of the answers did that) or interpreted as within a single process.

awk can do the latter readily enough, since it can perform more than one gsub in succession:

cat test.sh | awk '{gsub(/\\n/,"\n"); gsub(/\\t/,"\t"); print;}'

But (addressing the question if taken literally), awk could not do that in a single gsub call. You probably could do that using perl, but certainly not in sed, etc.

Upvotes: 1

Quixrick
Quixrick

Reputation: 3200

You can use a conditional from the command line with PERL, like this:

perl -pi -w -e 's~(?:(?<NEWLINE>\\n)|(?<TAB>\\t))~$+{NEWLINE}?"\n":"\t"~egi' file_name.txt

All that's happening here is that it is trying to match either a \\n or a \\t and I assign them names by adding the ?<NEWLINE> or ?<TAB> before it.

Next, it checks to see if the named group <NEWLINE> has been matched with this:

$+{NEWLINE}?

And if so, then it will replace it with a newline.

"\n"

Otherwise :, it will replace it with a tab.

"\t"

Upvotes: 0

Will Barnwell
Will Barnwell

Reputation: 4089

sed -i -e 's|\\n|\n|g' -e 's|\\t|\t|g' test.sh

Sed can execute multiple scripts in one command

s          # substitute
 |         # open capture block
  \\n      # match literal '\n' instead of the newline character
     |     # close capture block, open replacement block
      \n   # replace with newline character
        |  # close replacement block
         g # match multiple times per line

-i edits the file inplace

-e marks a script to be executed

Upvotes: 2

Related Questions