|
Programming C, bash, Python, Perl, PHP, Java, you name it. |
|
Thread Tools | Display Modes |
|
|||
How to append text to second line of a file
Say for example I have a text file like:
Code:
1 3 4 |
|
||||
The correct way depends on whether you want to edit the file or create a new file with the append.
If you want the same file to become Code:
1 3 2 4 Something like this should work: Code:
Terry@vectra$ cat > testfile 1 3 4 Terry@vectra$ ed -s testfile << EOF > 2 > a > 2 > . > 2,3j > wq > EOF 2 Terry@vectra$ cat testfile 1 3 2 4 Terry@vectra$
If you're not particularly familiar with interactive work, the '>' is my shells $PS2, used for such cases; so you don't type it in a ksh script. Like wise the << EOF thing is called a here document. In a shell script, it would look like this: Code:
ed -s testfile << EOF 2 a 2 . 2,3j wq EOF # rest of your shell scripts code here If you want a new file with the edits, you'll have to get a little creative with pipe lines and some of the tools for joining lines. You could also replace the ed script with an ex script, thus allowing an easier "Save as" like command to be used but the portability of ex script varies by the users competency for portability. ed scripts on the other hand are pretty darn universal.
__________________
My Journal Thou shalt check the array bounds of all strings (indeed, all arrays), for surely where thou typest ``foo'' someone someday shall type ``supercalifragilisticexpialidocious''. |
|
|||
|
|
||||
For standards compliance you would want to look at some of the usual but less well known text manipulation tools:
Code:
comm select or reject lines common to two files http://www.opengroup.org/onlinepubs/9699919799/utilities/comm.html csplit split files based on context http://www.opengroup.org/onlinepubs/9699919799/utilities/csplit.html cut cut out selected fields of each line of a file http://www.opengroup.org/onlinepubs/9699919799/utilities/cut.html fold filter for folding lines http://www.opengroup.org/onlinepubs/9699919799/utilities/fold.html join relational database operator http://www.opengroup.org/onlinepubs/9699919799/utilities/join.html paste merge corresponding or subsequent lines of files http://www.opengroup.org/onlinepubs/9699919799/utilities/paste.html split split files into pieces http://www.opengroup.org/onlinepubs/9699919799/utilities/split.html I have a file in my Dropbox that lists most of the programs covered by the last SUS spec, sans SCCS, things that should be built into the shell, etc.
__________________
My Journal Thou shalt check the array bounds of all strings (indeed, all arrays), for surely where thou typest ``foo'' someone someday shall type ``supercalifragilisticexpialidocious''. |
|
||||
Hi.
Here is an alternate method for sed, as well as an awk solution. The center code is the important part, the beginning lines are to show the environment of execution: Code:
#!/usr/bin/env bash # @(#) s2 Demonstrate append string to specific line with awk, sed. # Section 1, setup, pre-solution. # Infrastructure details, environment, commands for forum posts. # Uncomment export command to test script as external user. # export PATH="/usr/local/bin:/usr/bin:/bin" set +o nounset pe() { for i;do printf "%s" "$i";done; printf "\n"; } pl() { pe;pe "-----" ;pe "$*"; } C=$HOME/bin/context && [ -f $C ] && . $C sed awk -V set -o nounset pe FILE=${1-data1} # Section 2, display input file. # Display sample of data file, with head & tail as a last resort. pl " Contents of data file $FILE:" cat $FILE # Section 3, solution. pl " Results, awk:" awk ' NR == 2 { print $0, 2; next } { print } ' $FILE pl " Results, sed:" sed '2s/$/ 2/' $FILE exit 0 Code:
% ./s2 Environment: LC_ALL = C, LANG = C (Versions displayed with local utility "version") OS, ker|rel, machine: OpenBSD, 4.2, i386 GNU bash 3.2.17 sed - ( /usr/bin/sed Aug 28 2007 ) awk version 20041222 ----- Contents of data file data1: 1 3 4 ----- Results, awk: 1 3 2 4 ----- Results, sed: 1 3 2 4 |
|
||||
SED is a stream oriented version of ED .
The problem is, sed doesn't work like ed for editing files, which results in $ sed -e 'expr' infile > outfile instead of simply editing the file in place, and the only time you can rely on sed being able to edit a file in place is when it is GNU SED or a specific operating system that supports a comparable feature.Which means for portability reasons, if you're editing in place, ed and perl are your winners.
__________________
My Journal Thou shalt check the array bounds of all strings (indeed, all arrays), for surely where thou typest ``foo'' someone someday shall type ``supercalifragilisticexpialidocious''. |
|
||||
Hi.
My take on this is that the in-place options on most utilities are something of a misnomer. The data is written to a scratch file, then copied back onto the original -- one does not get something for nothing. This is true of "-i" on GNU sed, as well as the interactive editors ed/ex. So that the in-place description refers to the result rather than the method. To be sure, in place options are useful devices for convenience, but one could as easily use sed/awk with a utility like sponge: http://linux.die.net/man/1/sponge , part of moreutils, source at http://kitenet.net/~joey/code/moreutils/ , or write a scratch file oneself. There are times when I use the interactive editors ex/ed in scripting mode, but it's far more often as a demonstration that it can be done, rather than to do it in practice. The operation of ed/ex compared to sed/awk is different in the sense that -- at least with sed -- most often a line is read in, operated upon, and written out. The ed/ex editors will read in the entire file (possibly making an index of the locations of the lines on a scratch file), so that the memory demands can be significant. In most of the situations I have seen, sed/awk is far more often used than is ed/ex for scripting tasks. However, when the file is small enough and certain requirements are present -- such as addressing a line before a line that matches a pattern -- then ed/ex can be quite useful. There are adherents of sed on comp.unix.shell, but I think the flexibility and speed of GNU awk makes it a tool that one finds oneself reaching for more often than for sed. For the everyday tasks of dealing with fields of data, I have not found a more useful utility than awk. For mimicking the data-tool-connecting philosophy of *nix, I have found perl better, in that it deals with command-line options better than does awk. For example, the module Getopt::Euclid automatically will produce documentation and an option parser from one set of documentation sequences (POD mark-up). Externally, then, one could ask for Code:
perl-script-name --man Best wishes ... cheers, drl ( Edit 1: typo ) Last edited by drl; 8th November 2010 at 10:46 AM. |
|
||||
Quote:
Anotha' (similar) awk solution: Code:
$ cat file 1 3 4 $ awk 'NR==2{$0=$0" 2"}1' file 1 3 2 4
__________________
The best way to learn UNIX is to play with it, and the harder you play, the more you learn. If you play hard enough, you'll break something for sure, and having to fix a badly broken system is arguably the fastest way of all to learn. -Michael Lucas, AbsoluteBSD |
|
||||
Point being, you have to write your own w command in shell script when using sed, and some people choose to for awk as well.. Which means dealing with temporary files by hand. For those who think it's simple,
$ command file > file.bak && mv file.bak file is not perfect for every situation.You know, fewer moving parts the fewer things that can break.
__________________
My Journal Thou shalt check the array bounds of all strings (indeed, all arrays), for surely where thou typest ``foo'' someone someday shall type ``supercalifragilisticexpialidocious''. |
|
|||
There is no right way to do things, it's just a matter of preference.. use what's available.
|
|
||||
I think the point drl was getting at is that just because those moving parts are "behind the scenes" doesn't mean they don't exist. Is it harder to screw with it and mess stuff up if you can't see it? Sure...but that doesn't mean a well-written script is more prone to failure just because it doesn't hide the steps from you.
|
|
|||
Quote:
emacs --batch -Q --file file.dat --eval '(when (zerop (forward-line)) (end-of-line) (insert " 2") (save-buffer))' |
|
||||
Quote:
It's a question of responsibility, do you trust your copy/paste drill over an existing program? Why should you reimplement the same exact moving parts in shell, for each script you would want to make such a change in - when you have a tried and tested tool for doing it that has existed for over 35 years. It's just a waste of time. Coding hours should be spent on things that actually contribute to the program, not a substitute for learning the standard issue stuff. Quote:
__________________
My Journal Thou shalt check the array bounds of all strings (indeed, all arrays), for surely where thou typest ``foo'' someone someday shall type ``supercalifragilisticexpialidocious''. |
|
||||
Quote:
And yes, I trust my scripting skills to do the job right. (And no, I'm not saying I don't trust the tried and true code). |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Text to speech (save to file) - text2wave broken | godfrank | FreeBSD Ports and Packages | 2 | 23rd May 2010 02:13 AM |
Text screwed in Qt4 line edits (etc) | TerryP | FreeBSD Ports and Packages | 0 | 12th November 2009 04:01 AM |
avidemux2 command line | roddierod | FreeBSD General | 1 | 10th November 2008 08:27 PM |
shell: how to take part of the line... | graudeejs | Programming | 8 | 6th September 2008 11:13 PM |
TCSH - getting to start of line | maxrussell | FreeBSD General | 3 | 4th July 2008 11:55 AM |