Tag Info

New answers tagged

3

Here is one method: $ v='\n*******************************************************************************************************************************************************************\n' $ awk -v ORS="$v" '{print;}' file ...


0

If it's safe to assume that the first file contains the full list of keys, i.e. students, you can simply do the appending for each record first. Then, during END, you'll need to sort the keys, trim the appended values and back-fill the missing values with "NA": $ awk -F\| '{k=$1 FS $2 FS $3;r[k]=r[k] FS $4;c[k]++} END{n=asorti(r,s); ...


0

I tried this and it is working /usr/xpg4/bin/awk 'NR==FNR {h[$1,$2,$3]=$4; next}{print $0,($1,$2,$3) in h?h[$1,$2,$3]:"NA"}' FS=\| OFS=\| file2.txt file1.txt


0

Try this. Builds an array as with your example and just prints merged fields via END { ... }. $ awk -F\| '{ k=$1 FS $2 FS $3; h[k] = (k in h) ? h[k]=h[k] FS $4 : $0 } END { for(x in h){printf "%s%s\n",h[x],(length(h[x])>38) ? "" : "|NA"}}' file1.txt file2.txt|sort Student1|Class 1A|27|20140804 08:16:54|20140805 08:16:54 Student2|Class 1B|15|20140804 ...


2

awk can do that all alone: df -B KB | awk 'NR!=1&&$1!~/tmpfs|cdrom/{printf "'$(date "+%Y-%m-%d-%H:%M:%S")','$(hostname)',%s,%s,%s,%s\n", $2, $3, $4, $1}' Explanation: df -B KB: prints the values in KB awk NR!=1: avoid the first line $1!~/tmpfs|cdrom/: if the first field contains not the excluded filsystems printf: print formatted $(date ...


0

awk -F"\t" -v OFS="\t" '{ if (FNR==NR) { a[FNR]=$1;b[FNR]=$2;c[FNR]=$3} else { if (a[FNR] == $1 && b[FNR] ==$2) { $6=c[FNR]} else {$6=$6}; print $0 } }' file2 file1 I think this will do the work. First it will save the 1st,2nd and 3rd column of file 2 to array a,b and c resp with index as ...


0

try awk 'NR == FNR { data[$1 " " $2]=0 ; next ; } { if ($1 " " $2 in data) data[$1 " " $2]+=$3 } END { for ( d in data ) printf "%s %d\n",d,data[d] ;} ' filter data (this can be in one line) where NR == FNR { data[$1 " " $2]=0 ; next ; } store line from filter file { if ($1 " " $2 in data) data[$1 " " $2]+=$3 } add value from third colum if in data ...


0

Since you're using bash, let it do the base-2 conversion for you: while read a b c d do printf "%x %x %x %x\n" $((2#$a)) $((2#$b)) $((2#$c)) $((2#$d)) done < /path/to/file


1

Its an inelegant hack, but it works. Declares a function b which takes a binary representation of a number and returns the decimal value. Then relies on printf and its %x to show in hex. $ awk 'func b(i, t,a,c){a=1;for(c=length(i);c>0;c--){t+=substr(i,c,1)=="1"?a:0;a*=2}return t}{printf "0x%x 0x%x 0x%x 0x%x\n",b($1),b($2),b($3),b($4)}' bin.txt 0xf0 ...


1

awk only doesn decimal, octal and hexadecimal, not binary. You could use perl instead: perl -lane 'BEGIN{$, = " "} print unpack "(H2)*", pack("(B8)4", @F)'


1

This substracts 3 from columns 1 and 3: $ awk '{$1-=3; $3-=3; print;}' file 88 N 88 H 1.48 92 N 92 H -0.26 94 N 94 H 1.79 95 N 95 H -0.76 -= is the usual subtract-from operator. It works the same in awk as it does in C or python.


2

Assuming gnu awk is ok here.... Here's one way, it gives the number of days difference. But that isn't strictly what you want (2015-11-02 thru 2015-08-02 is 92 days and you want a result of 90). $ awk -F, '{ gsub(/-/," ",$0); print (mktime($6 " 00 00 00")-mktime($9 " 00 00 00"))/86400 }' file.txt -7765.04 -8898.04 -274 97 92.0417 $


2

From the question I assume you want to count all months as 30 days. In this case you don't need to use external tool (like date), just calculate number of days by yourself: awk -F'[,-]' '{print 360*($6-$11)+30*($7-$12)+($8-$13)}' file -7652 -8770 -270 95 90


1

Another answer, you could use vi/vim! qdjddq And then if your file was 500 lines (for example) type 250@d And then to write and exit type :x Or if something goes wrong and you don't want to save: :q! Explanation: q #Start Recording d #Put the recording into register 'd' j #Move the cursor down dd #Delete the line ...


1

Another option (shorter) sed 'n; d' file


46

Solving this by deleting every second line can be error prone (for example, when process sometimes generates two meaningful lines instead one). May be it is better to filter out the garbage: grep -v "No error occurred" file It can run as filter, you can add more garbage patterns here and improve the result.


4

Here is a way using sed: sed -n 'p;n' filename Another way with GNU sed: sed -n '1~2p' filename Output from above commands: Data inserted into table. Total count 13 Data inserted into table. Total count 45 Data inserted into table. Total count 14 Data inserted into table. Total count 90


9

Ассоrding to the question, with GNU sed: sed '0~2d' file will delete every second line but I'd like to offer filter lines by it content: sed '/Data/! d' file or with same result sed '/No error/d' file


17

With sed: sed -e n\;d <file With POSIX awk: awk 'FNR%2' <file If you have older awk (like oawk), you need: oawk 'NR%2 == 1' <file With ex: $ ex file <<\EX :g/$/+d :wq! EX will edit the file in-place. g mark a global command /$/ match every lines +d delete the next line wq! save all changes This approach share the same ideal ...


3

You can try with awk: awk 'NR % 2 != 0' file or you can print only lines containing Data inserted: awk '$0 ~ /Data inserted/' file


1

cat YOUR_FILE | cut -d'#' -f1 It uses # as column separator and keeps just the first column (that is everything before #).


0

Try this, it will help you. Open the file in vi editor: $ vi /file/location :1,100 s/^/DMS/ --> Enter 1,100 is exactly from which line you want to start and end. s is the substitution command and ^ means the the line starting. Or you can do it without opening the file, using GNU sed: sed -i 's/^/DMS /' /your/file/location


4

POSIXly: n=2 awk -F, '++a[$1]==ENVIRON["n"]' <file Occurrence of 1st field was track by increasing each time it was seen, saving in array a. If it's 2nd occurrence, the condition became true, making awk to print $0.


3

The answers in Turn off buffering in pipe provide several techniques which you can use. The principal idea is that commands which are not connected to an interactive terminal (for example, in a pipeline) are using buffering. One command which can run another command with different buffering settings is the GNU coreutils stdbuf command which you can apply to ...


2

With sed: sed '/^$/{$!{N;/\n$/D;s/.//;$!h;$p;d};};//!{H;1h;$!d};$x' infile this should print the last set of non-empty lines without any leading/trailing empty lines. e.g. iostat -d 1 2 | sed '/^$/{ # if the line is empty $!{ # and if it's not the last line N # then pull in the next line ...


2

Ignoring the fact that in your example, you could (should) just print each field $1, $2, etc., split returns the number of elements in the array, so to loop through them in the order they appeared you can use something like this: echo 'The quick brown fox jumped over the lazy dog.' | \ awk '{ n = split($0, WORDS, " "); for (i = 1; i ...


5

You're not printing the elements of the array, you're printing the fields in order. In awk, variables are not prefixed with a $, that's fields. So, $a will print the field of whatever number is stored in a. To print a variable, say foo, you need print foo, no $. When you iterate over an awk array, you are iterating over the array's indices: $ echo 'The ...


6

Firstly, for (i in array) in awk yield the index of array, not the array elements. So you got the result like you accessed $1. $2... $NF. echo 'The quick brown fox jumped over the lazy dog.' | \ awk '{ split($0, WORDS, " "); for ( WORD in WORDS ) { print WORD; } }' 2 3 4 5 6 7 8 9 1 You can see you got ...


1

You don't have to cut by -character count. Instead, you can cut on a specified -delimiter. grep '^<gc type="global"' <infile | cut -d\" -f4 80 81 82 That gets only the 4th "-delimited field on a line. And so that field can be as many characters - or digits if you prefer - as you like, so long as none of them are double-quotes. But you don't ...


0

You could grep to find the lines with 'type="global"' and then use sed to extract the values within the quotes after 'id=':' $ grep 'type="global"' /tmp/foo | sed -e 's/^.*id="\([0-9]*\)".*$/\1/' 80 81 82 ...


1

You could use GNU grep: grep -oP 'FREEBYTES.*percent="\K[0-9.]+' file Or sed: sed -n '/FREEBYTES/{s/.*percent="\([0-9.]*\).*/\1/p}' file Or GNU sed: sed -rn '/FREEBYTES/{s/.*percent="([0-9.]+).*/\1/p}' file64 Or awk: awk '/FREEBYTES/{sub(/.*percent="/,""); sub(/".*/,""); print}' file Or perl: perl -ne 'print if ...


1

It looks like what you want is to i) append the contents of file1 to file2 and ii) change the format of file2 to match that of file one. That is not what your question is actually asking for but it's what you show in your output. If I misunderstood, please edit your question and clarify. So, to do that, you could simply do: awk 'NR>1{printf ...


0

any field can be pick up from an XML file, for instance with xyz.xsl having <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output type="text" /> <xsl:template match="//XYZ"> <xsl:value-of select="@percent" /> </xsl:template> </xsl:stylesheet> a mere ...


0

awk -F[=\"] '/<XYZ FREEBYTES/ {print $9}' This will find the line with <XYZ FREEBYTES match and print 9th filed with delimiter = and ".


1

try awk 'FNR == NR { print ; next ; } NR > FNR && FNR > 1 { split($0,A) ; printf ",%s,,,,%s,,,\n",A[1],A[2] ; }' f1 f2 (can be in one line, I break it to be more readable) where FNR == NR { print ; next ; } copy lines from first file NR > FNR && FNR > 1 select line from second file without ...


0

awk -F[=\"] '{ a[FNR]=$0; if ($6>l && $0 ~ "<gc type=\"global\""){ l=$6;f=1;s=FNR }; if($0 ~ "</gc>" && f==1 ){ e=FNR;f=0 }} END{ for (i=s;i<=e;i++) { print a[i] }}' This will print the block starts from <gc type="global" till </gc> that has largest id. All ...


3

The GNU sed solution needs -i for inline editing: sed -i 's/$/ 1/' file.txt (With BSD sed, you need sed -i '') In awk, you have to work around that with a temporary file: awk '{ print $0 " 1" }' file.txt > tmp && mv tmp file.txt In fact, sed also creates a temporary file, but -i handles that The Problem with awk '{ print $0 " 1" }' < ...


2

This produces the output you're looking for, and it does not have to store the whole file in memory. awk -v diff=16 ' NR>1 && $1-prev > diff { print "----" while ($1-prev > diff) { prev += diff print prev } print "----" } { print prev = $1 } ...


-1

#!/bin/bash while read -r j do [ -f "$j" ] && bzip2 -dc "$j" | sed -r '/^([^\t]+\t){6}0*([1-9][0-9]{2,}|[6-9][0-9]|5[1-9])/! d' > "${j%.*}" done <"$1"


3

You could get them all in a single output stream like: bzip2 -dc ./File_*.bz2 | filter To write them out to separate files on output you'd need to delimit the stream in some way. This would be the ideal solution if you could arrange it - and with more information you could get help in doing so. Else you can call up your filters individually once per ...


0

try while read f do bzip2 -dc "$f" | awk -F '\t' 'BEGIN{OFS=FS} $7 > 50' > "$(basename "$f" .bz2)" done < list-of-file.txt awk will write result from File_1.tsv.bz2 to File_1.tsv, and so one with File_2, ... File_960. you give the list of file in list-of-file.txt > $(basename $f .bz2) will create result in local dir


0

In bash, you can try this: for f in `cat $1` do bzip ... done This may not work in all shells, and there are undoubtedly other ways to accomplish this. $1 means "the first parameter passed to the script".


1

From a user's perspective, a nice & simple Unix tool that does the job perfectly is qsubst. For example, % qsubst foo bar *.c *.h will replace foo with bar in all my C files. A nice feature is that qsubst will do a query-replace, i.e., it will show me each occurrence of foo and ask whether I want to replace it or not. [You can replace unconditionally ...


3

Using uniq instead awk can be quicker a little: sort -t, -k18,18nr -k21,21nr | uniq -s39 -w4


7

I don't see why you would want to do it in a single awk command, what you have seems perfectly fine. Anyway, here's one way: $ awk -F, '(max[$18]<$21 || max[$18]==""){max[$18]=$21;line[$18]=$0} END{for(key in line){print line[key]}}' file 6598,6598,0,1,,1,0,1,1,0,0,0,1,0,0,0,0,1390,1390,,0.730000, ...


1

You can try following awk: awk -F"," '{ if (max[$18] < $21) { max[$18] = $21; x[$18] = NR; } z[NR] = $0; } END { for (i in x) print z[x[i]]; }' file It uses 3 arrays max and x with keys of column $18 and z with keys row numbers . In max we hold max values, in x we are holding number of row containing max value, and in z every row in file. In the END ...


0

With sed: sed -e 's/\(I|\)[^|]*$/\10758000/;s/\(A|\)[^|]*$/\10800000/' file1.txt The point is to substitute everything that comes after I| or A| (i.e. last column) with desired numbers. Result: Z89|EEE333333|100001|JANMC84|19990101|I|0758000 Z89|EEE444444|200001|JANMC84|19990101|I|0758000 Z89|EEE222222|300001|JANMC84|19990101|A|0800000 ...


1

You can do it with awk like awk -F\| 'BEGIN {OFS=FS} $6 == "A" {$7 = "0800000"} $6 == "I" {$7 = "0758000"}; 1' file1.txt This will have awk split fields based on |, then set the output field separator to also be | when we write the lines back out. Then if the sixth field, $6, is A replace the seventh field with a particular value, and a different value ...


4

Without line breaks, grep is buffering all of the input, so that it can show you the "line" where the string appears. Two questions: Do you need the adjacent content? are there spaces or other characters separating the tokens? If you don't need the context of the adjacent content and there are spaces separating tokens, just use tr to turn spaces into ...


1

If you interested just in SUM grep -cf <(sed s/^/\^ACTIVE,/ city_name) siteDBName or for big files grep -f city_name siteDBName | grep -c ^ACTIVE



Top 50 recent answers are included