New answers tagged

3

awk is good for this, but you could do it simpler, with calcc() { awk "{\$$1=$2;print}" | column -t } Whether that's better or not is your choice.


0

This solution user "123" created for me on another question was able to strip suffixes reliably without mangling words. I wanted to come back and answer this question so that anyone seeking a similar solution could get a good answer. awk 'FNR==NR{a[$0 "s"]++;next}!($0 in a)' file.txt file.txt awk 'FNR==NR{a[$0 "ed"]++;next}!($0 in a)' file.txt file.txt awk '...


0

If you want to specify the relevant column numbers by hand and then just use awk to print out two sums at the end, you can do: awk 'NR == 2 || NR == 3 || ... {sum1 += $1} NR == 1 || NR == 11 || ... {sum2 += $1} END {print sum1; print sum2}' file


-1

Using only sed (with -r flag for extended regex) echo "aaa string1 bbb aaa string2 bbb aaa string3 bbb" | sed -r 's/(aaa|bbb) ?//g' Returns string1 string2 string3 You also have this version using tr and grep (with -vE): echo "aaa string1 bbb aaa string2 bbb aaa string3 bbb" | tr ' ' '\n'| grep -vE '(aaa|bbb|^$)' Returns string1 string2 string3 ...


1

If your system's grep supports PCRE, you could maybe do $ echo 'aaa string1 bbb aaa string2 bbb aaa string3 bbb' | grep -oP '(?<=(aaa|bbb) )\w*?(?= (aaa|bbb))' string1 string2 string3 or if you need to handle more general amounts of surrounding whitespace $ echo 'aaa string1 bbb aaa string2 bbb aaa string3 bbb' | grep -oP '(aaa|bbb)\s+\K\w*?(?=\s+...


0

If you are fine with something structured like: string1 string2 string3 I would just simply replace you delimiters with a newline. Something such as this should get you close: sed "s/\(aaa\)\|\(bbb\)/\n/g" test.txt Edit As pointed out by @clk below, my first answer may give double newlines. Changing to something such as: sed "s/\(\s\)\?aaa\(\s\)\?/...


1

I used a combination of grep and sed to accomplish your goal of after \n( and before )\n grep -o '\\n(.*)\\n' test.txt|sed -e 's/\\n//g' Sample output (T.a = 1) (public.cde.newcol = \'013\')


1

You can accomplish this with sed like so: sed -e 's,\\n(.*,,' unset or with awk you have to do a lot of escaping awk -F'\\\\n\\(' '{print $1}' unset to get the right escaping for both the \ before the n and to protect against the special interpretation of the (


0

With sed: sed -e 's/\<\([0-9.]\+\)-/-\1/g' or sed -E -e 's/\<([0-9+]+)-/-\1/g' With GNU awk: awk '{$0=gensub(/\<([0-9.]+)-/,"-\\1","g"); print }' NOTE: requires GNU awk for gensub() function. Neither sub() nor gsub() support capture groups. With perl: perl -p -e 's/\b([\d.]+)-/-$1/g'


2

You can accomplish this with awk awk '{sub(/".*",/,"");print}' filename


0

Instead rely on the SQL to fix the problem: create table #Tempt (Value VarChar(100)) Insert Into #Tempt Values(NULL) Insert Into #Tempt Values('500.1-') Insert Into #Tempt Values('-500.1') Insert Into #Tempt Values('20.5') select *, case when Value like '%-' then '-' + replace(value,'-',') else value end From #Tempt Then use the bulk insert to pull ...


2

With sed: echo 00000012- | sed -e 's/\([0-9]+\)\(-\)\?/\2\1/' gives -00000012. That is, matching two groups, the first with digits and the second with a sign, but using zero-or-more matches of that, and then replacing the two interchanged.


1

Some solutions to your problem without the loop # use bash's mapfile with process substitution mapfile -t arr < <( awk '!x[$0]++' <<<"$list" ) # use array assignment syntax (at least bash, ksh, zsh) # of a command-substituted value split at newline only # and (if the data can contain globs) globbing disabled set -f; IFS='\n' arr=( $( awk '!...


0

If I understand your index generation correctly, then awk '{print 5*(NR-1)+1" "$0}' yourfile > oufile should do it. If you want prettier output, you can use printf instead e.g. $ awk '{printf "%-3d %s\n", 5*(NR-1)+1, $0}' yourfile 1 4.184 4.2648 6 4.2281 4.0819 11 4.2204 4.1676 16 4.0482 4.1683 21 4.0156 4.2895 26 4.4504 5.2369 31 4....


2

awk '!x[$0]++' <<< "$list" | while read -r line; do array[count++]=$line done The array (italic) in this case is a part of the subshell (bold). The $line and $array has a value whilst the subshell is alive, so to speak. Once the subshell finishes, aka dies, the parent (spawner) environment is restored. This includes obliteration of any ...


0

Create an index-column on the original data file, using pr -t -n. Create the index data to be inserted as the new column, with each row of index data indexed by the row number. I used a little bash function to do this below. Join the index column with the data using join. Here's a bash script to demonstrate: #!/usr/bin/env bash # insert-counts.sh cols='/...


2

I think this does what you want; it accepts an awk variable named "factor" that is can easily be set to whatever you want: awk -v factor=8.06573 '{printf "%2.9f %2.9f\n", $1 * factor, $2 * factor}' With the given input, it outputs: 34.193855762 35.948152037 34.220472671 33.078365303 34.585043667 33.260650801 33.961562738 36.169959612 34.176917729 33....


0

with GNU sed sed -r 's/^([^.]+)\.[0-9]+ /\1 /' filename ^([^.]+) capture starting string upto first dot character \.[0-9]+ match dot character followed by more than 1 digit characters and if number of characters is consistent as given in the example, sed -r 's/^(.{8}).{7} /\1 /' filename


2

I would use awk awk --posix '{ gsub(/\.[[:digit:]]{6}/, "", $1); print }' filename Will target the first field (space delimited) and search for a . followed by 6 numbers and empty it out.


1

With awk probably the simplest way is to do a regular expression substitution on the first whitespace-separated field, replacing everything from the period to the end of the field: awk '{sub(/\..*/,"",$1)}1' somefile


31

Variables are referenced by name as in var, not $var in awk. $n refers to the nth field: $1 for the first field, $2 for the second... or the whole record for n == 0 ($0 is the full record). Those don't have to be literal numbers. You can use $(1+1) or $variable. If variable contains 1, then $variable will be the first field. A commonly used one is $NF for ...


0

I tend to use Perl. sed or awk is fine in this case, but sometimes the flexibility is Perl is useful. perl -pi -e 's/^(mynetworks.*)/$1 0.0.0.0\/0/' /path/to/file or if this is in a pipe chain cat file | perl -pe 's/^(mynetworks.*)/$1 0.0.0.0\/0/'


1

To add the specified text to a line in the file - if that line is the only one that starts with mynetworks, you can do this: sed --in-place '/^mynetworks/s_.*_& 0.0.0.0/0_' /path/to/file


3

Using sed sed -i 's+^mynetworks.*+& 0.0.0.0/0+' log.txt Using awk awk '/^mynetworks/ {$0=$0" 0.0.0.0/0"} 1' log.txt or awk '{if ($1 ~ /^mynetworks/) print $0, "0.0.0.0/0"; else print $0}' log.txt Using bash while read -r line ; do [[ $line == mynetworks* ]] && line+=" 0.0.0.0/0" echo "$line" done < log.txt


0

The join utility merges lines of two files based on a common column. It requires the files to be sorted on that column. join -t $'\t' -1 10 -2 1 -o 2.1,2.2,1.7 <(sort -t $'\t' -k10 file1) <(sort -t $'\t' file2) $'\t' is a tab character, -t $'\t' says to use that as the field separator. join -1 10 -2 1 means to join lines when the field 10 of the ...


0

If you want all lines with column 3 outside your limits then simply awk '$3>=210 || $3<=180 {print}' If you want just the first such line until the data is back inside the limits then: awk '$3>=210 { if(!hi)print; hi=1; lo=0; next } $3<=180 { if(!lo)print; lo=1; hi=0; next } { hi = 0; lo = 0 }'


0

try sed -e 's/^.*"\([^" ]*\)"".*/\1/' log | sort | uniq egrep -o '[^"]+@[^"]+' log | sort | uniq where -o print only matched pattern [^X]+ any number (> 0) of char different from X please note sed solution relays on a typo/feature in your file (double double quote) grep solution relays on foo@some.where pattern awk (or perl for that matter) is ...


1

#!/bin/bash filename="" do_write=0 while read line do case $line in ==*Result*) do_write=1 ;; ==*Test*) do_write=0 filename="" ;; Name*) [[ $do_write == 0 ]] && filename=${line#Name }.txt ;; "") # Skip blank lines ;; *) [[ $...


1

Here's one way: $ awk '(/=====/){a=0} (/\(Result\)\s*$/){a=1; next} ($1=="Name"){n=$2} (a==1){print >> n".txt"}' file Explanation (/=====/){a=0} : if the current line matches ======, set a to 0. (/\(Result\)\s*$/){a=1; next}: if the current line ends with(Results)followed by 0 or more whitespace, setato1` and skip to the ...


0

With perl you can have this way, #!/usr/bin/perl use strict; use warnings; my $file=$ARGV[0]; open my $fId, '<', $file or die "Error opeining file <$file>."; my @qty = (); my @price = (); my @discount = (); while(<$fId>){ chomp; my @fields = split (/\t/, $_); push @qty , $fields[1] if $fields[0] =~ m/Quantity/; ...


0

Everything can be done within single awk command by building big array with all data, but if the file is very big you may have problems with available memory. Thus I would do this in several steps: header=$(awk '{print $1}' file | uniq | tr '\n' ',') printf "${header%?}\n" > output paste -d, <(awk '$1=="Quantity"{print $2}' file) \ <(awk '...


0

I would try something like: awk -v pattern="Testing:" '$0 ~ pattern { sub(pattern, " *"); print }' Frankly, I don't see why you are messing around with the newlines.


0

use c (change operator) in sed: sed -e '/ServerName/c ServerName www.mydomain.com' FILENAME


0

Using sed substitue command: sed -i 's/ServerName/ServerName www.mydomain.com/' file.txt


1

sed --in-place 's/ServerName/& www.example.com/' /path/to/apache-vhost.conf


1

Using sed: sed 's/^\(ServerName\)$/\1 www.mydomain.com/' file.txt The captured group, \(ServerName\) is used in the replacement pattern as \1. Editing the file in place, with backup, assuming the GNU, ssed, busybox or some BSD implementations of sed: sed -i.bak 's/^\(ServerName\)$/\1 www.mydomain.com/' file.txt The original file will be kept as file....


0

POSIX Awk; this works with an arbitrary amount of files, and the files don’t even have to have the same amount of lines. The script keeps going until all files are out of lines: BEGIN { do { br = ch = 0 while (++ch < ARGC) if (getline < ARGV[ch]) { printf ch < ARGC - 1 ? $0 ";" : $0 RS br = 1 } } while (br) }


6

As steeldriver said, the reasonable way to do this is with paste: $ paste -d';' file* 1.001;2.001;3.001;4.001;5.001;6.001;7.001;8.001 1.002;2.002;3.002;4.002;5.002;6.002;7.002;8.002 1.003;2.003;3.003;4.003;5.003;6.003;7.003;8.003 1.004;2.004;3.004;4.004;5.004;6.004;7.004;8.004 But, if you must use awk: $ awk '{a[FNR]=a[FNR](FNR==NR?"":";")$0} END{for (i=...


0

I found this very useful for collecting log files from S3 Cloudfront and loading them into Google Drive. I used awscli on Mac-Os after installing this with homebrew awscli. I ran the command : aws s3 sync s3://bucketname/domain/ . The bucket was filled with cloudfront logs (I turn this on at the cloudfront edit) and all the files where pulled to my ...


3

#! /usr/bin/awk -f /"dvorak"/ {dvorak++}; /{/ && dvorak {b++} ; /}/ && dvorak {b--} ; dvorak && b == 0 && NR > 1 { print NR; exit } $ ./find-dvorak.awk /usr/share/X11/xkb/symbols/us 248 This uses a counter (b) which gets incremented every time it sees an open-curly-bracket { and decremented whenever it sees a ...


4

This sed script prints the line number of the line matching /^};/ in the range of lines from /xkb_symbols "dvorak" {/ to the next /^};/ (which will be the same }; as the one we get the line number for): /xkb_symbols "dvorak" {/,/^};/{ /^};/= } If you need both start and end line numbers: /xkb_symbols "dvorak" {/,/^};/{ /xkb_symbols "...


0

Old question but given that the last time I saw a single core personal computer was a decade ago, you can use gnu parallel To solve the shell expansion and interpretation of quotes my_awk='ORS=NR%3?" ":"\n"' Use the proper glob to select the input files. Here I'm using {.} to take out the extension from the output name because I'm appending it ...


2

As you mentioned in the comment you want to check current date's file in remote directory, you can do that in following manner: FILE=$(ssh -q "$USER"@"$HOST" 'find /home/oracle/SABARISH/logs/sftp -type f -daystart -mtime -1 | wc -l') if test "$FILE" -eq 0; then exit else # do your SFTP stuff here fi from man find : -daystart Measure ...


0

A sed solution: /:\./! { s/^.*://; H } /:\./ { G; s/\n/ /g; s/\. //; s/$/./p; s/.*//; x }


4

You may omit the OFS=" " I think, but the RS="" (or equivalent) is essential in order to put awk into paragraph mode. From the GNU awk manual, 4.8 Multiple-Line Records (other awks behave similarly, AFAIK): Another technique is to have blank lines separate records. By a special dispensation, an empty string as the value of RS indicates that records ...


0

An awk solution was posted, so I'll do a grep-based one. First, create a file with dates that you don't want to see, one per line. This will only be 15 entries, so it's not much processing needed and is quick. The following requires GNU date, which on my [BSD] system is installed as gdate: i=0 while (( i < 15 )); do gdate -d "now -$(( i++ )) days" +"...


0

You could use: awk -v threshold=$(date "--date=$(date) -14 day" +%Y%m%d) -F "'" '$2 < threshold' filename | wc -l This is similar to the solution in this post except that the date is computed inline. Note: filename should be replaced by the name of your file. Also, remember to be careful with your rules for boundary dates (check the edge conditions).


0

$ cat tst.awk BEGIN { FS=":" } { if ($2==".") { ORS = "\n" OFS = "" cnt = 0 } else { ORS = "" OFS = " " cnt++ } print (cnt==1 ? $0 : OFS $2) } $ awk -f tst.awk file student:xxxxx yyyyy zzzzz kkkkk. teacher:aaaaa bbbbb lllll. student:sssss mmmmm. If it's not obvious how that works you can ...


0

None of the answers above mention how to save the changes to the original file, which is I think what the OP was asking for. It's certainly what I needed when I cam to the page. So assuming your file is called output.txt sed -i '1 a This is the second line' output.txt My particular use case is to automatically add an xsl stylesheet declaration to a ...


0

sed -i 's/;$/,new-text-string;/' filename Will find the last occurrance of the ";" and append the new data before it. The -i makes it an in place change to the file from the command line.



Top 50 recent answers are included