Replace a string in all files - Unix

12,413

Solution 1

find . -name "./td/*.c" -exec sed -i "s/:::/::/g" '{}' \;

No need for od/ at all.

EDIT:

A slightly simpler variation:

ls td/*.c | xargs sed -i '' "s/:::/::/g"

Solution 2

A simple loop to process each file with sed should suffice.

for inp in ./td/*; do
    fname=${inp##*/}
    sed 's/:::/::/g' "$inp" > ./od/"$fname"
done
Share:
12,413
alvas
Author by

alvas

食飽未?

Updated on July 28, 2022

Comments

  • alvas
    alvas almost 2 years

    I am trying to replace a string ::: with :: for all lines in a batch of txtfiles (it can be considered as a word since there's always a space in front and behind it.

    I can do it with python like below, but is there a less 'over-kill' / convoluted way of doing this through the unix terminal? (Many pipes allowed)

    indir = "./td/"
    outdir =  './od/'
    for infile in glob.glob(os.path.join(indir,"*")):
      _,FILENAME = os.path.split()
      for l in codecs.open(infile,'r','utf8').readlines():
        l = l.replace(":::","::").strip()
        outfile = codecs.open(os.path.join(outdir,FILENAME),'a+','utf8')
        print>>outfile, l
    

    Then i move all files from od to td mv ./od/* ./td/*

  • Idelic
    Idelic about 11 years
    Simpler and much more efficient as well. You can make the find version just as efficient if you use + instead of \; at the end.
  • Sorin
    Sorin about 11 years
    -1 for using ls to handle file names. I would add another one for missing the obvious "simpler" solution sed -i ... td/*.c (with a globstar added if needed). And another one for using directory names in find's -name option (see: linux.about.com/od/commands/l/blcmdl1_find.htm)... How did this get 4 votes ?
  • Beta
    Beta about 11 years
    @Sorin: I admit I don't account for special characters in source file names (figuring that those who use them deserve what they get), but apart from that I don't see the problem. Kudos for your td/*.c suggestion though, I didn't know that would work; I'd've added it to my answer (with attribution) if it had been suggested with more courtesy.
  • Sorin
    Sorin about 11 years
    I don't know if I need to laugh or to cry.` sorin@sorin:~/tmp$ find -name "./tc/*.c" find: warning: Unix filenames usually don't contain slashes (though pathnames do). That means that '-name ./tc/*.c'' will probably evaluate to false all the time on this system. You might find the '-wholename' test more useful, or perhaps '-samefile'. Alternatively, if you are using GNU grep, you could use 'find ... -print0 | grep -FzZ ./tc/*.c''.`