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
Comments
-
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 about 11 yearsSimpler and much more efficient as well. You can make the
find
version just as efficient if you use+
instead of\;
at the end. -
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 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 about 11 yearsI 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''.`