Tag Info

New answers tagged

0

Since the Schwartzian transform has been mentioned, I'm surprised to see that no-one has yet posted a pure Perl implementation of one: perl -ne 'push @a, $_ }{ print map { $_->[0] } sort { $b->[1] <=> $a->[1] } map { [$_, $_ =~ tr/a//] } @a' file a man a plan a canal panama aardvark baseball cat bat bill Each line of the file is pushed to ...


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

Another Schwartzian transform: $ awk -Fa '{print NF,$0}' file | sort -nr | cut -d' ' -f2- a man a plan a canal panama aardvark baseball cat bat bill Or, in Perl: perl -Fa -lane 'print "$#F $_"' file | sort -nr | cut -d' ' -f2-


3

You can also just sort on the character: tr -cd a\\n <file | paste - ./file | LC_ALL=C sort -rk1,1 | cut -f2- Here's what your example looks like after being translated and pasted before it is piped into sort: aa baseball aaa aardvark aaaaaaaaaa a man a plan a canal panama a cat a bat bill Then sort gets it and, all things being equal, ...


5

The general approach with this kind of task is to use awk or perl... to compute the metric you're interested in and prepend it to the line, and then feed that to sort and remove the metric off the sorted output: awk '{print gsub("a","a"), $0}' < file | sort -rn | cut -d' ' -f2-


0

#!/bin/bash cat input.txt | while IFS= read -r a; do b=${a//[^a]} echo "${#b} $a" done | sort -rn | sed 's/[^ ]* //'


1

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 ...


1

With GNU grep: grep -oP '\b\w*a+\w*\b' file


1

awk 'BEGIN{RS="[[:space:][:punct:]]"; c=0} index($0,"a"){c++} END{print c}' Using a version of awk that supports multi-character Record Separator (RS), eg. GNU awk, you can cause awk to read one word per record. Within that record, the index(in, string) function searches in for the first occurrence of string, and returns the 1-based character ...


5

Here's a Perl way: perl -0lnE 'say scalar grep(/a/,split(/\s/,$_));' file And an awk way: awk '{for(i=1;i<=NF;i++){if($(i)~/a/){k++}}}END{print k}' file


8

POSIXly: <file tr -s '[:space:]' '[\n*]' | grep -c a Here, words are sequences of non-spacing characters.


14

Suppose that we have this test file: $ cat file the cat in the hat the quick brown dog jack splat With grep implementations that have adopted GNU's -o extension, we can retrieve all the words containing a: $ grep -wo '[[:alnum:]]*a[[:alnum:]]*' file cat hat jack splat We can count those words: $ grep -wo '[[:alnum:]]*a[[:alnum:]]*' file | wc -l 4


1

If your paragraphs are always separated by a single empty line: sed '/^$/s/^/\x02/' infile | tr \\n$'\002' $'\003'\\n | \ sed 's/^\x03//;1s/\x03$//;1!G;h;$!d;$a\' | tr $'\003' \\n It's quite easy to see how it works if you break it into pieces and run sed '/^$/s/^/\x02/' infile then sed '/^$/s/^/\x02/' infile | tr \\n$'\002' $'\003'\\n and so on... 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 ...


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

BASH-only solution read file into bash array ( one line = one element of array ) and print out array in reverse order: i=0 while read line[$i] ; do i=$(($i+1)) done < FILE for (( i=${#line[@]}-1 ; i>=0 ; i-- )) ; do echo ${line[$i]} done


1

sed "$(printf '$!N;/\f')"'\n/,/\n./!P;D' <in >out ...should work provided a POSIX compliant shell, printf, and sed. You don't really need printf though if you just insert the character literally. You can usually do it with CTRL+V then CTRL+L. So... sed '$!N;/^L\n/,/\n./!P;D' <in >out ...where the ^L sequence above is got by doing CTRL+V ...


4

With ksh93, bash, zsh, mksh, recent FreeBSD sh: sed $'/\f/,/./{/\f/d;/./!d;}' That will fail if there are consecutive sequences of \f\n\n...s though. With GNU sed, you can omit the $. POSIXly ($'...' is not POSIX yet, though will probably be in SUSv5): FF=$(printf '\f') sed "/$FF/,/./{/$FF/d;/./!d;}" Note that the current POSIX spec requires a ...


4

That's the caret notation for the form feed character. With the GNU implementation of sed, you can remove it using its octal value, \o14 : sed 's/\o14//g' file You can also use its escape code: sed 's/\f//' file Such characters can be entered in the terminal by pressing CtrlV and then the code for the character. In this case, CtrlL. So, type this: ...


4

POSIXly you can get the decimal value of a hex number like: hex=10 echo "$((0x$hex))" 16 And you really don't need to do all of those [ tests ]. I think the following should work: case $f7 in (EnHr|EnSt|SpJb|Chem|[BT]rTm|PmTm|HyTm) printf "\t\t\t\t\t%s%b" \ "HEX VALUE is" ":\t$f10" \ '' "inside case loop.\t\t" \ Sen ...


0

The standard in error comes from bc. It expects hex values in upper case. So instead of 0019c4ef you should pass it 0019C4EF. The hex to dec conversion can be done using without bc too- see this answer http://stackoverflow.com/a/13280173/3935925


0

For both questions, the error came from bc. 0019c4ef is an invalid hex number in bc, you need 0019C4EF for a valid hex number: echo "ibase=16; 0019C4EF" | bc 1688815 Because you used bash (also work in ksh, zsh, mksh, pdksh, posh), you can use [base#]n where base is a decimal number between 2 and 64: $ echo "$((16#0019c4ef))" 1688815 In your case, ...


0

The following works: sed -e'/-/!N;/;\n/!b' <i >o \ -e's//:/;y/ /\n/;:n' \ -e's/^\(\([^:]*\).*\)\n/\1 \2:/;tn' Or, with -Extended regular expression syntax (which will work at least w/ AST/BSD/GNU seds): sed -Ee'/-/!N;/;\n/!b' <i >o \ -e's//:/;y/ /\n/;:n' \ -e's/^(([^:]*).*)\n/\1 \2:/;tn' ...which isn't terribly ...


0

Answer for First Version of This Question (Before the Data Changed) $ awk '/^[^;]*[[:alpha:]];/{a=$1; if (NR!=1)print"";getline; gsub(/(^| )/, " "substr(a,1,length(a)-1)":");print;next} {print " "$0;}' file MX04A:DMX04A; MX04A:DMX04A; MX04A:LMX04A; MX04A:LMX04A; -17.2; -15.3; -14.3; -13.6; -16.8; -15.4; -16.0; -15.3; LH36A:DLH36A; LH36A:DLH36A; ...


0

Here's a start, that at least works with the example data: sed -r '/[A-Z];/{N;s/([^;]+);\n([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+)/\1:\2 \1:\3 \1:\4 \1:\5/;3,$s/^/\n/};s/^/ /' input.txt This is assuming the following: Line 1 of each record will always have some uppercase letters Line 2 of each record always directly follows line 1 Line 2 of each record always ...


1

I would think the quickest way to do it would look something like... sed -e's/./& /g;i\' -e'<item>' \ -ea\\ -e'<tag><out>=' <file | paste -d'\0 ""' - - - ./file /dev/null This also works: ( set -- - - - - - - /tmp/file paste -d'<item> <tag><out>="' "$@" - - - - - - "$@" | sed 's/ ...


1

You can do it without loop in awk: awk '{a=$1;gsub(/./,"& ",$1); print "<item>"$1"<tag><out>=""\""a"\""}' numbers.txt Output: <item>9 3 7 4 5 4 1 6 3 2 5 5 3 <tag><out>="9374541632553" <item>5 1 2 4 3 7 4 7 8 7 9 8 4 1 <tag><out>="51243747879841" <item>3 2 0 3 0 0 9 8 8 9 6 9 1 4 ...


1

Here's one way you might be able to do the whole thing in sed: sed ' h; s/./& /g; s/.*/<item>&<tag>out=/; G; s/\n\([0-9]*\)/"\1"/; ' numbers.txt


-1

How about this... cat numbers.txt | while read line; do echo $line | sed -r "s/([0-9])/\1/g; s/([0-9])/\1 /g ; s/^/<item>/g; s/$/<tag>out=\"$line\"/g" ; done Or, cat numbers.txt | while read line; do echo "<item>$(echo $line | fold -w1 | paste -s -d' ') <tag>out=\"$line\""; done


1

Because both read and sed are taking data from stdin. In the while loop, you read the first line into $line. Then sed starts: you don't give it any other input so it reads from stdin, which is the output of cat numbers.txt. So sed will consume the rest of the input. And since you're still in the first iteration of the while loop, the $line variable doesn't ...


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 ...


2

With ed: ed -s infile <<IN g/^/m0 ,p q IN If you're on BSD/OSX (and hopefully soon on gnu/linux too): tail -r infile


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 ...


2

How about: tr '|' '\n' | sed -n 's/=Y$//p'


1

perl -nE 'say join(",",/(\w+)=Y/g)'


2

awk can read records based on a regex delimiter of your choice. eg '[|\n]' It can also split records into fields on the delimeter of your choice. eg. '=' The ternary operator (condition)?: prevents a leading comma. awk -F= -vRS='[|\n]' '$2=="Y"{ printf (i?",":"")"%s", $1; i=1 }' output: p2,p6 If a trailing newline is needed, it can be appended in ...


6

Using Perl compatible regular expression in grep: grep -Po '..(?==Y)' <file Result: p2 p6


1

a simple awk awk -F\| '{for (i=1 ; i<= NF; i++) if ( $i ~/Y/ ) { split($i,A,"=") ; printf "in %d : %s\n",i,A[1] ;}}' where -F\| use | as separator {for (i=1 ; i<= NF; i++) scan through pattern if ( $i ~/Y/ ) if found { split($i,A,"=") ; printf "in %d : %s\n",i,A[1] ;} split it and print it output in 3 : p2 in 11 : p6 use printf ...


3

Try this: echo 'p1=X||p2=Y||p3=X||p4=X||p5=X||p6=Y||p7=X' | grep -o '[^|]*=Y' | cut -d= -f1 | sed -e 'N;s/\n/,/g' Output: p2,p6


0

Other way to escape double-quotes (and other special simbols) put all line(s) in single qoutes (if it is absent in your text): sed "s/^\|$/'/g" <sampleMetadata


2

With standard tools chest, sed is a good one: sed -e 's/"/\\&/g' <sampleMetadata


1

(hopefully) the final product find . -name \*.gz -type f -exec gzcat {} + | sed -ne'/^ *ID:/h;/No Profile/!d;x' \ -e's/^ *ID:\([^ ]*\).*/\1/p' So that will recursively find all of the regular files rooted in the current directory with filenames which match the pattern *.gz and call zcat as few times as is necessary to iteratively uncompress every ...


0

You can do it with awk (only tested with GNU awk) like awk '{print $0;match($2, /=(.*),/, arr); if(arr[1]!="") {print "changetype: modify\nadd:mail\nmail: " arr[1] }}' <input file> This will print each line print $0, then use match to pull out the email address. Then it will print the stanza you want, assuming it found an email address to print. ...


1

This might work for you: sed -e 's/.*cn=\([^,]*\).*/&\nchangetype: modify \nadd: mail \nmail: \1/'


3

GNU grep; cat: { grep -m1 'pattern' && cat || ! cat ./infile } <./infile POSIX sed; cat: { sed -ne'/PATTERN/q;H;1h;$!d;x;p'; cat; } <infile GNU sed; cat: { sed -une'/PATTERN/q;H;1h;$!d;x;p'; cat; } <infile (just add -u) sharing is nice All of the above commands work because the file-descriptor from which they read() is ...



Top 50 recent answers are included