Hot answers tagged

35

Numbers in AWK are floating-point numbers by default, and your value exceeds the precision available. 0xffffffffbb6002e0 ends up represented as 0 10000111110 1111111111111111111111111111111101110110110000000000 in IEEE-754 binary64 (double-precision) format, which is 0xffffffffbb600000. (See it in an online FP converter) The smallest integer to get any ...


10

Why use awk when, on most Unix boxes at least, you can just do: $ seq 6 | shuf 5 2 3 4 1 6 or as @StéphaneChazelas mentioned in a comment shuf -i 1-6. If you do want to use awk though then here's one approach using a Knuth Shuffle: $ cat tst.awk function shuf(arr, i, j, n, tmp) { n = length(arr) for (i=n; i>1; i--) { j = int( 1 + ...


7

To convert an string (that looks like a number) in awk: It could be assigned to a variable as a program constant. The function strtonum() could convert the text. Awk could be called with the option -n (now deprecated). Once converted to a number, in most awk (gawk, mawk, nawk, bawk), it is stored as a 64 bit floating point. Those numbers could include only ...


6

No need for awk, just use uniq directly, uniq -c -f 1 file The -c option gives the count for the number of times a line was found consecutively in the input, and you can skip the timestamp in the first space or tab-delimited field with -f 1. Example given the data in the question: $ uniq -c -f 1 file 1 18:56:54 Info: Starting 3 18:56:55 Error: timed ...


6

The syntax var=$(something) is shell syntax (and not awk) which means "run the command something and store the result in the shell variable $var". You seem to be expecting it to be somehow linked to your awk script since NR==2 etc are awk statements. That won't work. This command will print the output you expect: $ for file in file1 file2; do ...


4

Assuming GNU make: Add the shell keyword before the nvidia-smi command and double the dollars in awk command. The similarities in make n shell syntax are a source of confusion. ver_cuda: CUDA = $(shell nvidia-smi | awk -F"CUDA Version:" 'NR==3{split($$2,a," ");print a[1]}') VER_CUDA ?= $(CUDA)


4

You have FILE= (singular) and for f in $FILES (plural). Beyond that though, look at the difference in the output of the 2 echo statements below: $ ls tmp File-0 File-1 File-2 File-3 $ files=tmp/File* $ echo "$files" tmp/File* $ files=( tmp/File* ) $ echo "${files[@]}" tmp/File-0 tmp/File-1 tmp/File-2 tmp/File-3 You COULD get a list ...


4

It seems as if you just want to shuffle the numbers between 1 and 6. Most implementations of sort has an -R option to sort "randomly" (this option is not standard). Most shells have "brace expansions" to generate combinations of strings, or numbers in ranges (brace expansions are not standard): $ printf '%s\n' {1..6} | sort -R 6 2 3 4 5 ...


4

Use: awk -F'( )' '{ $1=toupper($1) }1' infile the use of the field separator in regex mode and single space we defined with -F'( )' is to keep the indentation between the fields and keep the output beauty as input is, if you don't like beauty output, just remove it.


4

In awk, the last field value is accessible by the $NF, second last $(NF-1), etc based on the field separator. so you need awk -F, '$NF > 1' data Ps, and don't forget to fix the source program that produce that invalid .csv file at first place.


4

You can use vgs and tailor the output format instead, to reduce the number of steps: sudo vgs --units b --no-suffix --noheadings -o vg_name,vg_size,vg_free | awk '{ printf "%s %f%%\n", $1, $3 * 100 / $2 }' This forces output in bytes (--units b), removes suffixes and headings, and outputs only the VG’s name, total size, and free space, before ...


3

script #!/bin/bash m=$1 awk -F "|" -v m="$m" '$1 == m{print $2}' filename output sh script.sh 1 file1.txt sh script.sh 2 file2.txt sh script.sh 3 file3.txt


3

There are two problems here. First, if you want to write an awk script, you need to use -f in the shebang since awk requires a file, and using this is a workaround to let you use awk on the contents of the script. See man awk: -f progfile Specify the pathname of the file progfile containing an awk program. A pathname of '-' ...


3

Part of the problem is that you're using $(nvidia-smi ...) instead of $(shell nvidia-smi ...). That's easily solved. You also have to use $$2 instead of just $2 to prevent make from expanding it (probably expanding to nothing, resulting in the awk expression being just {print } and printing the entire line). e.g. with a minimalist Makefile: all: CUDA=&...


3

awk 'BEGIN{ FS=OFS="\t" }{ gsub(" ", "", $2) }1' infile FS is the input Field Separator; OFS is the Output Field Separator; both sets to a Tab \t character, then we remove (replaces with empty string) all the space characters within second field and print the final update with the 1 used.


2

With bash, one can do this, which handles an arbitrary number of commas in the address field: # function to join strings with a separator join() { local IFS=$1 shift printf '%s\n' "$*" } # process the file { IFS=, read -ra header join '|' "${header[@]}" f=${#header[@]} # expected num of ...


2

You haven't really explained how we can know which commas to keep and which to change. Based on the single example line you have given us, it might be enough to just replace all , that don't come after a space with a |: $ sed -E 's/,(\S)/\|\1/g' file Name|Age|Country|ID|Address|Category|DOB John Doe|19|England|3653|Manchester, England|Main Worker|20-05-1995 ...


2

Using any awk in any shell on every Unix box: $ awk -F, -v OFS='|' 'NF>7{$5=$5",\n"; sub(/\n./,"")} 1' file Name,Age,Country,ID,Address,Category,DOB John Doe|19|England|3653|Manchester, England|Main Worker|20-05-1995 $5=$5",\n" adds a , and a newline (which can't otherwise be present in the current record since records are ...


2

With awk you can try: awk -F, -v OFS='|' 'NR==1{print $0} NR>1{$5 = $5 FS $6; print $1,$2,$3,$4,$5,$7,$8}' file Name,Age,Country,ID,Address,Category,DOB John Doe|19|England|3653|Manchester, England|Main Worker|20-05-1995


2

Assuming the user's input is in the variable userinput, then the following awk code will generate a never-ending random sampling of that input. userinput=$userinput awk ' BEGIN { s = ENVIRON["userinput"] "\n" n = length(s) while (1) printf "%s", substr(s,int(1+rand()*n),1) }' This ...


2

Perl perl -MList::MoreUtils=all -F'\t' -lane ' print if all { /^comp-/ } @F[0,1]; ' file sed GNU version $ sed -n '/^comp-.*\tcomp-/p' file


2

Make that first line call the shell interpreter and not awk, as in #!/usr/bin/env bash


2

If you're happy with the count at the beginning of the line, uniq is all you need: $ uniq -f 1 -c log.txt 1 18:56:54 Info: Starting 3 18:56:55 Error: timed out 1 18:56:58 Info: reconnected 1 18:56:59 Error: timed outhet -f 1 skips the first field, -c counts the lines. To get the exact format you asked for, you need to process uniq'...


2

Using the LC_NUMERIC='en_US.UTF-8' locale (that has supporting the comma as the thousands separator formatting for the numbers) and using the sprintf's %\047d (%\047d is just another type of writing single quote %'d using the Octal Escape Sequences, or you can write it %'\''d too) format modifier to force convert the floating point numbers into integers plus ...


1

This modified script adds support for single numbers: #! /bin/bash civic="$1" street="$2" if [ "$((civic%2))" = 1 ]; then exclude=" even " else exclude=" odd " fi </path/to/addresses.txt grep -E "(^| )$street" \ | grep -v "$exclude" \ | awk -F '[ -]' -v civic="$civic&...


1

command uniq -f 1 -c filename| awk '{print $2,$3,$4,$5,$1}'| awk '{if($NF > 1){$NF="("$NF")";print }else{$NF="";print }}' output 18:56:54 Info: Starting 18:56:55 Error: timed out (3) 18:56:58 Info: reconnected 18:56:59 Error: timed out


1

Using the awk utility we can arrive at the unique count of events as follows: $ awk ' {t=substr($0,1+index($0,FS))} prev != t { if (NR>1) {fx(line,knt)} knt = 0 prev = t }{ line = $0 knt++ } END {fx(line,knt)} function fx(a,b) { print a (b>1?sprintf("%s(%d)",OFS,b):"") } ' file 18:56:54 Info: Starting 18:56:57 Error: ...


1

awk -F, ' { printf "%s %s %s", (NR==1 ? substr($2, 1, 14) : ""), substr($2, 1, 18), $3 } END{ print "" } ' latest.csv This prints the first substring only for the first input record. The other substring plus $3 is printed for all records. In the END block, print a newline.


1

I'd do this as: sort -t, -k3,3 student.csv | awk ' BEGIN { FS=OFS="," } $3 != prev { close(out) out = $3 FS "out.csv" prev = $3 } { print $1, $2 > out } ' || exit 1 for file in *,out.csv; do email="${file%,*}" send email to "$email" containing "$file" done


1

With perl: perl -pe 's/\S+/\U$&/' < input.txt > output.txt That would convert to uppercase the first sequence of non-spacing characters on each line. If the input contains non-ASCII characters and is encoded in UTF-8, add the -CS option. If it's encoded as per your locale's charset, add -Mopen=locale instead. If your input has columns with fixed ...


Only top voted, non community-wiki answers of a minimum length are eligible