Replace specific columns in fixed width files using sed
I have this string in my data file (dat.txt) =>
00000
10101
I want to replace the 1st row, second and fourth column, I tried this:
$>sed -i "/^1/s/0/1/2" dat.txt
$>sed -i "/^1/s/0/1/4" dat.txt
But when I reload the开发者_JAVA百科 dat.txt, it does not change anything. Is my command wrong?
Try this:
sed -i '1{s/./1/2;s/./1/4}' dat.txt
Result:
01010
10101
For a start, unless that first line is your zeroth row, you'll be changing the second (the one that begins with 1
).
And that 2
and 4
don't change the second/fourth column, they change the second/fourth occurrence of the search pattern.
See the following transcript:
$ cat dat.txt
00000
10101
$ sed -i "/^1/s/0/1/2" dat.txt ; cat dat.txt
00000
10111
$ sed -i "/^1/s/0/1/4" dat.txt ; cat dat.txt
00000
10111
You can see that the first sed
changed the second occurrence of 0
to 1
, and that was in the fourth column. The second sed
changed nothing since you asked it to do it to the fourth occurrence and there aren't four 0
characters there.
If you want to change specific columns, you can use capturing patterns, as in the following transcript:
$ cat dat.txt
00000
10101
$ sed -i "/^1/s/^\(.\)0/\11/" dat.txt ; cat dat.txt
00000
11101
$ sed -i "/^1/s/^\(...\)0/\11/" dat.txt ; cat dat.txt
00000
11111
The parentheses capture the pattern so that \1
in the replacement text can be used to refer to that captured text. Because you're talking about a small number of characters before the one you want to change, you can use ...
as a pattern. If you wanted to change (for example) the 85th column, you'd probably be better off with something like:
sed -i "/^1/s/^\(.\{84\}\)0/\11/" dat.txt ; cat dat.txt
The number after the substitution is the number of the instance to change, not the specific character. There is no fourth instance so the second has no effect, whereas the first should change the second line to 10111
.
This should do it:
sed -i -e '1 s/0/1/2' -e '1 s/0/1/3' dat.txt
-e
means add a command, so they execute one after another. You can also use this:
sed -i '1 s/0/1/2; 1 s/0/1/3' dat.txt
Note that, in your question, /^1/
part before s
command to sed means: change all rows that begin (^
means 'match start of the line') with 1
. Look here:
- http://www.grymoire.com/Unix/Sed.html#uh-26
in particular the section the link points to (Restricting to a line number) and the next (Patterns) section.
精彩评论