Tag Info

New answers tagged

0

A short alternative in Perl: perl -pe 'BEGIN{$n=3} 1 while s/old/new/ && ++$i < $n ;' your_file Change the value of `$n$ to your liking. How it works: For every line, it keeps trying to substitute new for old (s/old/new/) and whenever it can, it increments the variable $i (++$i). It keeps working on the line (1 while ...) as long as it has ...


3

Say you want to replace only the first three instances of a string... seq 11 100 311 | sed -e 's/1/\ &/g' \ #s/match string/\nmatch string/globally -e :t \ #define label t -e '/\n/{ x' \ #newlines must match - exchange hold and pattern spaces -e '/.\{3\}/!{' \ #if not 3 characters in hold space do -e 's/$/./' \ ...


1

A simple, but not very fast solution is to loop over commands described in http://stackoverflow.com/questions/148451/how-to-use-sed-to-replace-only-the-first-occurrence-in-a-file for i in $(seq 50) ; do sed -i -e "0,/oldword/s//newword/" file.txt ; done This particular sed command probably works only for GNU sed and if newword is not part of oldword. ...


3

Using Awk The awk commands can be used to replace the first N occurrences of the word with the replacement. The commands will only replace if the word is a complete match. In the examples below i am replacing the first 27 occurrences of old with new Using sub awk '{for(i=1;i<=NF;i++){if(x<27&&$i=="old"){x++;sub("old","new",$i)}}}1' file ...


4

A job for perl: perl -pe 's/\bname\b\K/"_".++$n/ge'


0

In Simple Bash Script #!/bin/bash count=0 search="linux" while read line do for word in ${line} do if [[ $word == $search ]] then printf "${word}_${count} " ((count++)) else printf "$word " fi done echo done < input_file


1

Because this involves arithmetic, this is not a good problem for sed. However, awk can handle it: awk '{for (i=1;i<=NF;i++) { if ($i=="name") {c++;$i=$i"_"c} }} 1' For example: $ echo a name b name name c d name | awk '{for (i=1;i<=NF;i++) { if ($i=="name") {c++;$i=$i"_"c} }} 1' a name_1 b name_2 name_3 c d name_4 Explanation: {for ...


3

The first section belows describes using sed to change the first k-occurrences on a line. The second section extends this approach to change only the first k-occurrences in a file, regardless of what line they appear on. Line-oriented solution With standard sed, there is a command to replace the k-th occurrance of a word on a line. If k is 3, for ...


0

Yet another way: pr -a7 -l1 -s";" filename which is short for pr --columns=7 --across --length=1 --separator=";" filename


2

awk '{ ORS=NR%7?",":"\n" }1' is another way with awk.


5

If you're not stuck on sed or awk, use paste echo "R1 R2 R3 R4 R5 R6 R7 R1 R2 R3 R4 R5 R6 R7" | paste -d, - - - - - - - R1,R2,R3,R4,R5,R6,R7 R1,R2,R3,R4,R5,R6,R7 There's no difficulty with your 2nd sample, just have to quote the semicolon so the shell doesn't see it: paste -d ';' - - - - - - - <filename 00000;ND00000056888;Doe, Jane J;F;99 ...


4

try awk '{printf "%s%s",$0,NR%7?",":"\n" ; }' the big part NR%7?",":"\n" : if-then-else : if (NR%7) : NR, (Number of Record) % (modulo) 7 (divide by 7 != 0 ) then printf a ',' else new line. $0 is the whole line


0

For the general case of matching N times: $ perl -ple '$N=3;s/(\S+ ){$N}\K/\n/g' tmp word1 word2 word3 word4 word5 word6 word7


0

Another way in sed: $ sed 's/ /\x1&\x2/g; s/\([^\x1]*[\x1][^\x2]*[\x2][^\x1]*\)[\x1][^\x2]*[\x2]/\1\ /g; s/[\x1\x2]//g'


2

Sorry, seems like I figured it just after posting. It needs to be sed -e 's/\(word. \)\{2\}/&\n/g' tmp It seems the brackets are needed to let sed apply {2} condition on the entire pattern word. and not just preceding space.


7

Use the string you are looking for as the selector for the lines to be operated upon: sed '/ipsum/s/#//g' /ipsum/ selects lines containing "ipsum" and only on these lines the command(s) that follow are executed. You can use braces to run more commands /ipsum/{s/#//g;s/@/-at-/g;}


2

$ cat input.txt # lorem ipsum blah variable # lorem ipsum blat variable # lorem ipsum blow variable # lorem ipsum blip variable # lorem ipsum blue variable then: $ sed 's|# \(.*blue.*\)|\1|' input.txt gives: # lorem ipsum blah variable # lorem ipsum blat variable # lorem ipsum blow variable # lorem ipsum blip variable lorem ipsum blue variable It ...


1

The likely answer is that: The 30Gb file was not fragmented (or had very little fragmentation): all hard drives perform much better with sequential access (SSDs included) because they are able to cache large chunks of the file. This allows them to approach their maximum performance. Sequential access will help with all levels of caches. sed is a stream ...


1

One wonderful example is sed uses a temporary file to actually save the contents and then replaces the original file. For example, you can do a simple testing to find this. cat test This is a test file. Now, run ls -li to check the inode number. ls -li test 2368770 -rw-r--r-- 1 root root 22 Sep 12 08:46 test Now, issue the below sed command to add a ...


1

This is really not the best way to do this. Why save the files in an array? A simpler approach would be something like: path=/home/abc/allfiles filesall=(${path}/*) files=(${path}/*.csv) If you insist on doing it your way, you would have to do something like (but this breaks on files that contain newlines): files=$(for file in "${filesall[@]}"; do [[ ...


3

Nice markup: awk '!/^#/ && NF { split($2,a,"-") printf "%s - - [%s/%s/%s:%s] \"%s %s\" %s %s\n", $1, a[3], a[2], a[1], $3, $4, $5, $6, $7 }' file If your input is just the lines starting with 10.000... this makes it: $ awk '{printf "%s - - [%s:%s] \"%s %s\" %s %s\n", $1, $2, $3, $4, $5, $6, $7}' file 10.000.000.000 - - ...


0

From what I understand from your question you are trying to replace DEFINE tsdir = '/u02/app/oracle/oradata/orcl' by DEFINE tsdir = '/u02/app/oracle/oradata/${ORACLE_SID_VALUE}' If this is what you are trying to do , You can achieve this using sed -i "s#DEFINE tsdir = '/u02/app/oracle/oradata/orcl'#DEFINE tsdir = ...


1

I would try: sed -i -e "/DEFINE tsdir = /c\ DEFINE tsdir = '/u02/app/oracle/oradata/${ORACLE_SID_VALUE}' " schema-install.sql sed is confused by / in path definition.


1

Arguably simpler than glenn’s answer (although it does require typing “Start of script” twice): tac logfile | awk '/End of script/,/Start of script/{print} /Start of script/{exit}' | tac or tac logfile | sed -n '/End of script/,/Start of script/p; /Start of script/q' | tac


3

Perhaps a little state machine: tac file | awk '/End of script/ {p=1} p {print} p && /Start of script/ {exit}' | tac


1

{ { paste -d\ /dev/fd/[345] | sed 's/ \( [^ ]*\)\(.*\)/\2\1/' } 3<<FILE1 4<<FILE2 5<<FILE3 $(<file1 sed '1,/^1/w /dev/fd/2 /^2/,$!d;s/ [^ ]*//4;s// /3') FILE1 $(<file2 tr -s \\n) FILE2 $(<file3 tr -s \\n) FILE3 } 2>&1 In the above command sequence I do a fair amount of in/out juggling. It is pretty simply done. ...


-1

To edit every other (a.k.a. every second) line, starting with the first, in sed, do sed '1~2s/^/>/' your_file This will write the modified file to the standard output.  I.e., if you type just the above, the modified file will display on the screen.  You can put this into a new file by redirecting the output with a >; e.g., sed '1~2s/^/>/' your_file > ...


3

The input data is kind of paragraph-oriented, so let's read it as a paragraph instead of line-by-line: awk -v RS="\n=\n" ' /PRIMER_LEFT_NUM_RETURNED=[^0]/ { n = split($0, lines, /\n/) for (i=1; i<=n; i++) { if (lines[i] ~ ...


2

You can set the record separator to \n=\n, that is a newline, a = and then a newline again. That will let you use awk as you wish: $ awk -v RS='\n=\n' -v OFS="\n" '!/PRIMER_LEFT_NUM_RETURNED=0/{print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,RS}' file SEQUENCE_ID=Contig1 SEQUENCE_TEMPLATE=AAGTCGCCCCTCCAT PRIMER_LEFT_NUM_RETURNED=2 ...


1

The direct way: awk '$3 !~ "=0"{print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,RS}' RS='=\n' FS='\n' OFS='\n' file This will add an extra blank line after =, you can remove it easily if you want.


1

Since you haven’t asked for a 100% awk solution, I’ll offer a hybrid that (a) may, arguably, be easier to understand, and (b) doesn’t stress awk’s memory limits: awk ' $1 == 2 { secondpart = 1 } { if (!secondpart) { print > "top" } else { print $1, $2 > "left" print $5, $6, $7, $8, ...


0

Another awk way without arrays, its a bit of a mess so i'll try and clean it up later awk 'function get(file,L) {x=1 while ( (getline < file) > 0) {if(NR==x)y=$0;x++} close(file) return y } ARGV[1]==FILENAME{d=$0;a=get(ARGV[2],$0);b=get(ARGV[3],$0);$0=d;$2=a;$3=b;print }' file file1 file2


2

An awk way: awk '{if(FNR==NR){f2[FNR+1]=$1;} else{ if(FNR==1){k++;} if(k==1){f3[FNR+1]=$1} else{if($1~/^[0-9]+/ && $1>1){$3=f2[$1];$4=f3[$1];} print} }}' file2 file3 file1 This is the same thing written as a commented script for clarity: #!/usr/local/bin/gawk -f { ## NR is the current line ...


0

here is what i came up. your data are on a.txt, third column are on b.txt (I put weekday name for clarity, this will work as well with number.). mybox $ cat b.txt day monday tuesday wednesday thursday friday saturday mybox $ cat a.txt 1 4324 3673 6.2e+11 7687 67576 2 3565 8768 8760 5780 8778 3 7656 8793 -3e+11 7099 79909 4 8768 8965 8769 9879 0970 5 5878 ...


0

With awk you could try something like, awk 'NR % 4 == 1 {sub(/^/,">")} {print}' filename References http://stackoverflow.com/questions/2099471/add-a-prefix-string-to-beginning-of-each-line


0

With no blank lines between each line and no ' character at the start: $ awk '{print ((NR%2)? ">":"") $0}' passages.txt gives: >Sunshine This is a sunny day. >Darkness A cave is a dark place. Also, going by your responses to all the answers here, your input file isn't single lines with a Line Feed character at the end (\n). It might be worth ...


0

sed '1,${s/^/>/g;n;n;n}' filename Testing cat filename 'Sunshine 'This is a sunny day. 'Darkness 'A cave is a dark place 'Sunshine 'This is a sunny day. 'Darkness 'A cave is a dark place 'Sunshine 'This is a sunny day. 'Darkness 'A cave is a dark place After I run the command, I get the output as, sed '1,${s/^/>/g;n;n;n}' new ...


1

Most Linux: sed -i 's#FIND#REPLACE#g' *.{php,ini,conf,sh} On MacOS: sed -i '' 's#FIND#REPLACE#g' *.{php,ini,conf,sh} The sed in MacOS is expecting a backup parameter after -i, use empty string if you don't need backup files. The "g" is for global replace, otherwise it's only the first per row.


2

With GNU sed you can use sed -i. sed -i 'script' *.{php,ini,conf,sh}


2

Typically, when you get a > in the next line after hitting, it means that one of your quotes isn't closed yet. I couldn't find that mistake in your regex. But you do not need to surround the path /var/www_data/somepath/ with single quotes. I assume there are no unusual characters in somepath? Anyways, I tested your regex with sed. \d\w look like vim ...


1

Another perl perl -F, -lane 'print join ",", map {(/-$/ && chop) . $_} @F' file


0

Here are a few: A shorter perl one perl -pe 's/([\d.]+)-/-$1/g' file (GNU) sed sed -r 's/([0-9.]+)-/-\1/g' file Any sed sed 's/\([0-9.]*\)-/-1\1/g' file Gawk. Note that the various awk variants are not very good at tasks that involve capturing patterns. GNU awk (gawk) and others can do it but I would use one of the solutions above instead. gawk ...


1

Same as perl command, $ sed 's/\([0-9]\+\.[0-9]\+\)-/-\1/g' file 0.00,-70440.19,-18.31,0.00,-451.59,-13788.77,-44.19,-6289.29 -1.03,-39.24,-0.11,-16.96,0.00,-72377.70,0.00,-146673.67,-59.11,0.00 Another perl one-liner, $ perl -pe 's/([^,\n]*?)-/-\1/g' file 0.00,-70440.19,-18.31,0.00,-451.59,-13788.77,-44.19,-6289.29 ...


1

The below one worked: Any other awk or sed solution would be great to know... perl -pe 's#(\d{1,}[.]\d{1,})(-)#$2$1#'g file


0

You could use the below perl command, $ echo '192.9.200.12-14 172.17.200.12-89 12.21.1.10-25 127.0.0.1-127' | perl -pe 's/[^.]+\.[^.]+\.[^.]+\K\./,/g' 192.9.200,12-14 172.17.200,12-89 12.21.1,10-25 127.0.0,1-127


0

A portable shell function that will do this: u2dos() (set -f; IFS=' '; printf '%s\r\n' $(cat "$1")) With that you can do: u2dos file >dosfile


0

Here's an approach that makes use of sed. It identifies blocks within the strings that occur like so: .<digits>- When found, sed will remember the digits & - pieces and swap out the preceding . with a ,. $ echo "$IPS" | sed 's/\.\([[:digit:]]\+-\)/,\1/g' Example $ echo "$IPS" | sed 's/\.\([[:digit:]]\+-\)/,\1/g' 192.9.200,12-14 ...


0

In awk you can try awk '{print $0 "\r"}' Or awk -v r=$'\r' '{print $0 r}' The $'\r' is an example of ANSI-C style quoting. It offers a general way to express weird characters, try this, for example: awk -v r=$'\U1F608' '{print $0 r}'


0

Using GNU awk: awk -F, '$3' input_file


1

To emulate sed -i for a single file portably while avoiding race conditions as much as possible: sed 'script' <<FILE >file $(cat file) FILE By the way, this also handles the possible problem that sed -i introduces in that, depending on directory and file permissions, sed -i might enable a user to overwrite a file which that user does not have ...



Top 50 recent answers are included