Tag Info

New answers tagged

1

awk -F "\t" '$4 == "calc" {$4 = $3-$2}1' OFS='\t' file


6

Sed can't do arithmetic┬╣. Use awk instead. awk ' $4 == "calc" {sub(/calc( |\t)/, sprintf("%-6.2f", $3 - $2))} 1' The 1 at the end means to print everything (after any preceding transformation). Instead of the text substitution with sub, you could assign to $4, but doing so replaces inter-column space (which can be any sequence of spaces and tabs) ...


1

You can combine them using awk logical && and || (See more awk boolean operators): $ awk '(NF > 1 && $1 ~ /^[0-9]/) || (NF == 1 && $1 ~ /^[[:upper:]]/)' file NAME_1 11 11 You should use [[:upper:]] to match capital letter because [A-Z] only work in C locale.


0

awk -F"[:=]" -vRS='+' '{for(i=1; i<=NF; i++) {if($i == "prop1") I=$(i+1); if($i == "prop2") O=$(i+1)}; printf "input: %s -> output: %s\n", I, O}' file


2

For Expected output, awk '/^E/{$0=$2} /^F/{$0=$3}1' file If you want to print first field as well, awk '/^E/{$0=$1 FS $2} /^F/{$0=$1 FS $3}1' file


2

This should work awk '/^F/{$2=$3}NF=(NF-2)' file If you want to match E as well(if there are other things in the file) awk 'a=/^F/{$2=$3}{x=/^E/}(x||a)&&NF=(NF-2)' file


3

Try: awk '$1 ~ /^E/ {print $1,$2;next} $1 ~ /^F/ {print $1,$3}' file


5

awk '$1 ~ /^E|^F/ {if ($1 == "End") print $1" "$2; if ($1 == "Fin") print $1" "$3}' or awk '/^End/{print $1" "$2}/^Fin/{print $1" "$3}' (thanks to Jidder) Should work.


5

You could use awk as @Gnouc suggested, or GNU grep grep -P '^[^\s]+\s+[A-Z]' file Perl perl -lane 'print if $F[1]=~/^[A-Z]/' file GNU sed sed -rn '/^[^\s]+\s+[A-Z]/p' file shell (assumes a recent version of ksh93, zsh or bash) while read -r a b; do [[ $b =~ ^[A-Z] ]] && printf "%s %s\n" "$a" "$b"; done < file


6

You must use regex ^ to denote start of string: $ awk '$2 ~ /^[[:upper:]]/' file ID A56 DS AGE 56


2

sed -n '/ID.* s/p;//,/ID/{//!p;}' <<\DATA ID number1 string DS item11 DS item12 ID number2 not_string DS item21 DS item22 ID number3 string DS item31 DS item32 DATA That relies on this POSIX defined behavior for sed regex addresses: If an RE is empty (that is, no pattern ...


3

If I understand right, I change the not_string in your input for test: ID number1 string DS item11 DS item12 ID number2 qwerty ...


2

A shorter awk solution: $ awk -F',' '$(NF+1) = $5 > 0 ? "YES" : "NO"' OFS=',' file If your file contains windows newline character, you can remove it: $ awk -F',' '{sub(/\r$/,"")} $(NF+1) = $5 > 0 ? "YES" : "NO"' OFS=',' file


2

You can assign straight into fields in awk with $N, for N the field number: $9 = "YES" will add a new field at the end with the value "YES": awk -F, -v OFS=, '{ if ($5 > 5) { $9 = "YES" } else {$9 = "NO"} };1' data When we assign into $9 we create the ninth field, which is one beyond the end for this data. Putting 1 at the end forces awk's default ...


0

Here is an awk solution: $ awk -F '/|:' ' $3 == "8013765024" {flag = 1} $0 == ",11:1" && flag {$2 = 2;flag = 0} 1 ' OFS=':' file


1

Below mentioned solution might help: cat file_name.txt | fmt -w 80 > reduced_file_name.txt fmt - simple optimal text formatter.


3

Use fmt instead: fmt --width=80 file From man fmt: -w, --width=WIDTH maximum line width (default of 75 columns)


2

Since you state that the file is sorted, shouldn't it be possible to use a simple loop with memory for only the preceding appId string? Kind of like @Qeole's sed approach but avoiding the overhead of regular expresssions by using the shell's delimited read function plus string comparison: #!/bin/bash appId="" while IFS=\; read -r s1 s2 s3 userId; do if ...


0

For closure, this is the start of the script I am going to use. It needs more work to make it robust and do logging but you should get the general idea. #!/bin/sh # This script should be executed from a crontab that executes every 5 or 10 minutes # the find below looks for all log files that do NOT have the sticky bit set. # You can see the sticky bit ...


2

A sed answer: sed ': l;N;s/^\([^;]\+;[^;]\+;[^;:]\+\)[;:] *\(.*\)\n\1;\(.*\)/\1: \2, \3/;tl;P;D' input_file.txt File is read only once, so performance shouldn't be too bad, but I can't tell you more than that. With details: sed ': l; # Label l N; # Add next line of input to pattern space s/^\([^;]\+;[^;]\+;[^;:]\+\)[;:] ...


2

In Perl perl -F';' -lane 'push @{$h{join ";",@F[0..2]}},$F[3]; END{ for(sort keys %h){ print "$_: ". join ",",@{$h{$_}}; } }' your_file You should be able to do something similar in awk using associative arrays, but I'm not really that well-versed in awk ...


2

There's a dedicated tool for that: paste. It concatenates each full line from the first file with the corresponding line from the second file; you can remove unwanted columns before or after. For example, assuming that your columns are tab-delimited: paste file1.txt file2.txt | cut -f 1,2,3,6 Here's a way to pre-filter both files that relies on ...


5

An ugly way of doing this (i.e. causing a function call in shell based on output from awk) could look like this: awk -F '\t' ' FNR < 2 {next} FNR == NR { for (i=2; i <= NF; i++) { if (($i == 1) || ($i == 4)) printf "retrieve %s\n", $i if (($i == 2) || ($i == 2)) printf "retrieve2 ...


0

Try to use inotifywait for that: inotifywait -e close_write /home/tomcat/openam/openam/log/CURRENT_OPENED_LOG_FILE


1

Bernhard's answer is the correct one. For fun and completeness, bash: while read -a fields; do echo ${fields[-1]} done < file


1

awk is really the tool for the job here but for the sake of completeness here's a GNU grep way grep -oE '[^[:space:]]+$' file 7 8 9


3

You can use sed for such operation: sed 's/.* //' file # where ' ' -- is your delimiter It will delete all symbols before the delimiter. If your file is tab-separated, use: sed 's/.*\t//' file


3

If you want the last field only and not both first and last, you could try: rev file | cut -f 1 The rev reverses each line of the file and the cut prints only the first field (fields are defined by tabs by default). Since the line has been reversed, the first field is the original last field. The above works in your given example but, as @Bernhard points ...


13

You can make smart use of the NF variable in awk awk '{print $NF}' File1 From man awk NF The number of fields in the current input record. So NF will give you the amount of fields and $NF will then expand to $3 for example, which you can use in a print statement.


1

After some research, I found the answer. First, according to this: Expression Patterns An expression pattern will be evaluated as if it were an expression in a Boolean context. If the result is true, the pattern will be considered to match, and the associated action (if any) will be executed. If the result is false, the action will not be executed. ...


6

You have: $NF=a[FNR] as the final condition (the one that determines whether to print). Assignments return the value assigned, in this case a[FNR]. The first line of the data file from the linked question is: A 0 a[FNR] is initialised to $2. That means the value of a[FNR] is 0, which is a false value to awk. That means the assignment is false, which ...


1

Try this: $ awk 'FNR==NR{a[FNR]=$2;next}{$NF=a[FNR]}1' file2 file1 A 23 8 0 A 63 9 6 B 45 3 5


6

You should use -v option of awk: awk -F',' -v accNum="$1" '$1 == accNum {print $3,$2}' With $1 in double quote, the shell will handle all its special character ( if has ) for you.


2

Your script already practically does the job without any awk at all: while IFS=, read -r num last first do [ $((num==accountNum)) -eq 1 ] && printf '%s.%s\n' "$first" "$last" done < Accounts I'm not suggesting that this is a better or more efficient solution than using awk alone, but if you want the while...read loop, this ...


2

You have: accountNum=$1 awk -F',' '{ if($1==accountNum) { print $3.$2 } }' Accounts How does the shell variable accountNum get into awk? It doesn't: you need to provide its value to awk explicitly. You can use: awk -F',' '{ if($1=='"$accountNum"') { print $3.$2 } }' Accounts which leaves single quotes and has the shell substitute the value of its ...


3

Here's a Perl approach: $ perl -lane '@k=($F[1]=~/,/g); $i=$#k+2; $l=length($F[2]); print "@F $i $l ", $l/$i' file A 1,2,3 * 3 1 0.333333333333333 A 4,5,6 ** 3 2 0.666666666666667 B 1 1 0 B 4,5 * 2 1 0.5 Or, with printf for pretty formatting: $ perl -lane '@k=($F[1]=~/,/g); $i=$#k+2; $l=length($F[2]); printf "%s %-5s %-3s ...


1

This string literal in awk "echo \"select * from abc limit 1;\"| impala-shell|grep -Eo \" a-[0-9]-[0-9]* \| HS[0-9] \| [0-9]* \| [0-9]* \" " represents the following string value: echo "select * from abc limit 1;"| impala-shell|grep -Eo " a-[0-9]-[0-9]* | HS[0-9] | [0-9]* | [0-9]* " Backslash followed by another character which is not a letter or ...


6

You seem to be hoping that (NF","$2 -1) will be treated as a function that will return the number of comma-delimited elements in field $2 - it won't. NF is always the number of fields in the record. Instead, you can use awk's split function split($2,a,",") which splits field $2 into an array a and returns the number of elements. You can also tidy up the ...


1

Try this: $ awk -v SUBSEP=" " ' {a[$1,$2]++;b[$1,$2] = (b[$1,$2] && $3 > b[$1,$2]) ? b[$1,$2] : $3} END { for (i in a) { print i,a[i],b[i]; } } ' file A B 2 1990 A C 2 2001 A D 2 2001 B C 1 2013 Even shorter if you can change the order of field: $ sort -n -k1 -k2 -k3 file | uniq -c -w 3 2 A B 1990 ...


2

Personally, I would do this by taking advantage of the shell's brace expansion: $ while read a b; do echo $a $(eval echo {"$(sed 's/-/../' <<<$b)"}); done < file A 1 2 3 B 5 6 7 or, to have comma separated values $ while read a b; do echo $a $(eval echo {"$(sed 's/-/../' <<<$b)"} | sed 's/ /,/g'); done < file A 1,2,3 B ...


2

Try this: $ echo "A 1 2 3" | awk '{for(i=2;i<=NF;i++)printf("%s\t%d\n",$1,$i)}' A 1 A 2 A 3


2

Try this: $ awk ' FNR == NR { a[$1] = $2;next } { split(a[$1],b,","); for (i in b) { if ($2 == b[i]) { printf("%s %s\t*\n",$1,a[$1]); next; } } print $1,a[$1]; } ' file1 file2 A 1,2,3,4 * B 15,16,17 Update With your new input, try: $ awk ' FNR == NR ...


0

There is many ways to do it. Here is a perl: $ perl -ne 'print unless /:.{0,3}$/' file blue:fish red:tomato black:moon


0

This AWK command splits on : and prints lines which of which the second field is at least 4 chars (not less than 4 chars). Assumption: : is always present and does not occur multiple times. awk -F : "length($2) >= 4" If it occurs multiple times, then you could use $NF instead of $2 to refer to the last column.


2

You can use sed: sed -r -e '/:.{0,3}$/d' data -r uses extended regular expressions (for {}). The sed expression matches all lines with a colon followed by zero to three characters and then the end of the line; d deletes those lines. All the rest will be printed.


2

Use sort's -k option to sort by (multiple) columns at once: $ sort -k1,1 -k2n input A 1-2 A 3-4 A 6-8 B 5-9 B 7-10 -k1,1 sorts by the first column first, then -k2n by the second numerically when the first column was tied, so you get your output in the order you want: sorting by the first element of the second column, only if the first column ...


0

TXR language: @(do (defun csv-parse (str) (let ((toks (tok-str str #/[^\s,][^,]+[^\s,]|"[^"]*"|[^\s,]/))) [mapcar (do let ((l (match-regex @1 #/".*"/))) (if (eql l (length @1)) [@1 1..-1] @1)) toks])) (defun csv-format (list) (cat-str (mapcar (do if (find #\, @1) `"@1"` @1) list) ", ")) ...


0

Given two files containing unsorted lists of users, e.g. In file1: userD user3 userA user1 userB and In file2: user3 userB userX user1 then to get a simple list of the users in file1 but not in file2, you can do $ comm -23 <(sort file1) <(sort file2) userA userD and similarly to get the users in file2 but ...


0

Go for vimdiff for Showing differences between two, three or four versions of the same file.


1

diff [options] from-file to-file diff compares the contents of the two files from-file and to-file.You can specify the -i option that ignores changes in case; consider upper- and lower-case letters equivalent. For more information you can refer this link : http://www.computerhope.com/unix/udiff.htm or you can have a look at the manual page.



Top 50 recent answers are included