0

I'm trying to use the follow to substitute the tab with comma in several file:

#!/bin/sh 
for i in *output_*.txt  
do   
sed 's/ /;/g' $i > $i 
done

But it is not working because in the output file I still have the tab delimiter. It just work when I'm using it on a single file without the for loop.

Any help?

Thanks.

7
  • How are you inserting the tab character? bash takes tab as a completion, which can cause issues. Most sed's support \t for a tab, else tab=$'\t' then sed "s/$tab/;/g" $i > $i Commented Jun 25, 2012 at 8:14
  • it looks like you're substituting space for semicolon. try using sed -i 's/\t/,/g' $i. -i option means in place. Commented Jun 25, 2012 at 8:15
  • Try using the -i flag of sed that enables in-place substitution. Commented Jun 25, 2012 at 8:18
  • 1
    Be careful; I hope you've got copies of your data, because 'sed ... $i > $i' has the shell create an empty output file called $i before sed gets to read it. You cannot edit a file in situ like that. If you have GNU sed, there's a -i option. Otherwise, write to a temporary file and then copy the temporary over the original when done (or move the temporary). Commented Jun 25, 2012 at 8:18
  • You seem to be replacing a space (or tab) with a semi-colon, too, but that could just be a confusing layout. Commented Jun 25, 2012 at 8:20

2 Answers 2

3

Several things are wrong. Unqouted variables and output redirection into same file. Loop is also not needed.

Try: sed -i 's/ /;/g' *output_*.txt

Sign up to request clarification or add additional context in comments.

2 Comments

I have different file with different name so just sed -i 's/ /;/g' output_.txt will not work.
Yes but the problem is that I need to write to file. I was doing this by overwriting the original file. But has someone point out sed first create an empty file.
0

The correct script you need is as follows:

find . -name '*output_*.txt' | while read FILENAME; do
    (sed -e "s/\\t/;/g" <${FILENAME} >${FILENAME%.txt}.tmp) && (mv ${FILENAME%.txt}.tmp ${FILENAME});
done

This script has several important features:

  1. It finds all files called *output_*.txt in the current directory and all subdirectories. If you do not want to recurse into subdirectories, then use:

    find . -maxdepth 1 -name '*output_*.txt' | while read FILENAME; do
    

    as the first line.

  2. It does not overwrite your original input file if sed encounters an error. sed generates its output to a temporary file (<filename>.tmp) and it only replaces the original file if it is successful.

  3. As pointed out by other posters, the tab character is represented by \t in sed scripts.

An example transformation performed by this script is as follows (the sequence <tab> represents a tab character):

Input:

    <tab><tab><tab><tab><tab>line 1<tab><tab>
    <tab><tab><tab>line 2<tab><tab>
    <tab><tab>line 3<tab><tab>
    <tab><tab><tab>line 4<tab><tab>
    <tab><tab><tab><tab><tab>line<tab><tab> 5
    

Output:

    ;;;;line 1;;
    ;;;line 2;;
    ;;line 3;;
    ;;;line 4;;
    ;;;;;line;; 5

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.