Tag Info

Hot answers tagged

15

With tr: echo "Thhiisss iisss mmyyy nameeee" | tr -s 'a-z' Explanation: The -s switch of tr "squeezes" repeat characters. As shown, the switch can be used with a range of characters: a to z.


7

On a GNU system you'll need to use sed or similar if your locale uses multibyte characters (as jimmij suggests) because GNU tr can only reference a character per byte. In an ASCII locale you can remove all duplicates w/ tr like: LC_ALL=C tr -s '\0-\255' <input So... echo Thhiisss iisss mmyyy nameeee| LC_ALL=C tr -s '\0-\255' ...prints... This is my ...


6

One way with sed: sed ':X;s/\(.\)\1/\1/g;tX' or even simpler: sed 's/\(.\)\1*/\1/g' (thanks Costas and mikeserv for comments).


5

Let's compare all proposed solutions! I have a text file test.txt of size ~230M. I'm on Mac Mini, updated to 10.10. 1) awk solution by Hauke Laging (better not...): $ time bash -c "awk '/a/ && /b/ && /c/' >> /dev/null" 19.51 real 19.23 user 0.20 sys 2) "bruteforced" grep by Raghuraman R and Hauke Laging (better, but ...


5

Through grep which accept -P (Perl-regexp) parameter. $ grep -P '^(?=.*a)(?=.*b)(?=.*c)' file abc bca cab fhfhfhfabcjdfjdjfk ahfhfbkjfjdjffc Explanation: ^ Matches the start of a line (?=.*a) Only if the string going to be matched must contain a letter a (?=.*b) Must contain b (?=.*c) Must contain c


5

grep can do this with -o option: grep -o 'Foo=[^,]*' file


4

When you tee to multiple process substitutions, you're not guaranteed to get the output in any particular order, so you'd better stick with paste -t',' <(commanda < file) <(commandb < file) Assuming cat myfile stands for some expensive pipeline, I think you'll have to store the output, either in a file or a variable: output=$( some expensive ...


4

$ awk -F'[ (]' '{a[$1]=a[$1] $3 "\n"} END{for (name in a)print name "\n" a[name]}' loginFile bobby 2014-05-12 2014-06-12 bill 2014-06-12 How it works -F'[ (]' This tells awk to accept either a space or an open parens as the field separator. a[$1]=a[$1] $3 "\n" This stores the login dates for each user in an array a. END{for (name in a)print name "\n" ...


4

You could try this: $ sort -rt"," -k2,3 file.csv | awk -F, '{a[$2][$3]=$0; if(a[$2][$4]){print a[$2][$4]; print;}}' RZ_AUTO_7,4tow,131,132,98,99,UC/AC Canonical ribose-zipper RZ_AUTO_5,4tow,130,131,99,100,AU/CA Canonical ribose-zipper RZ_AUTO_2,4tov,1405,1406,1517,1518,GU/AA Naked ribose-zipper RZ_AUTO_1,4tov,1404,1405,1518,1519,CG/AA Canonical ...


4

You need to write your regular expression in a way that only matches whole words. With GNU sed, you can use \b which matches at word boundaries: sed -i "s/\b$word\b/$replace/g" If you know there will always be a space there, you could just add a space: sed -i "s/ $word /$replace/g" Now, there are also some issues with your script. Your if ... break ...


4

awk ' { a[NR]=$0 b[NR]=$2 } END{ for(i=1;i<=NR;i++){ k=i+1 printf("%s ",a[i]) for(j=k;j<=NR;j++) printf("%s ",b[j]) print "" } }' table.file At first script builds two arrays (a and b) with NR (row number) as index. Than add to each element of array a all elements of array b but without ...


4

With GNU grep linked to a recent version of the PCRE library (Perl Compatible Regular Expressions), you could try: $ grep -oP '<essid\b[^<>]*>\K[^<>]*(?=</essid>)' file WLAN-123651234 This would extract the contents of essid tag. Explanation: <essid matches exactly the string <essid \b called word boundary which matches ...


3

With zsh: pee() ( n=0 close_in= close_out= inputs=() outputs=() merge_command=$1; shift for cmd do eval "coproc $cmd $close_in $close_out" exec {i}<&p {o}>&p inputs+=($i) outputs+=($o) eval i$n=$i o$n=$o close_in+=" {i$n}<&-" close_out+=" {o$n}>&-" ((n++)) done coproc : read -p eval tee ...


3

If you're using a modern shell like bash or zsh, use $ so that the shell evaluates \t and replaces it with an actual tab: nl -ba -s $'\t' full_media > full_media2 Even so, if you examine the output, it looks like the default separator is a tab: $ nl -ba -s $'\t' ~/at.sh | od -c 0000000 1 \t n o h u p s g $ ...


3

Try the following awk-script: awk ' /<Person>/,/<\/Person>/{ if (! /<Name>/) a=a s $0 s="\n" } /<\/Person>/{ system("echo \""a"\" |md5sum - ") a=s="" }' input.xml Explanation: Collect all lines between tags Person into a variable When meet closing tag /Person call system command than empty a ...


3

It seems like if it's a tab. You can confirm this by placing your cursor on it and press ga in normal mode. If it displays <^I> 9, Hex 09, Octal 011 then it's a tab. A space looks like this: < > 32, Hex 20, Octal 040 To change each tab to a single space: %s/\t/ /g


3

Given the input you show, the following should work: <infile sed -e '$!N;2i\' -e '3k s|\(\(.* *\).*_1\)\n\(\(.* *\).*_2\)$|[\1 ]P\2d\4+/p[\3]pc|;t s|^[ _ID0-9]*|[&]pc|;P;D' | dc For me it prints... 10 ID1_1 .333 20 ID1_2 1 ID3_1 .100 9 ID3_2 20 ID20_1 15 ID2_1 .047 300 ID2_2 ...because I set dc's precision to 3, but with a precision ...


3

The awk solution to round up the list of alternatives: awk -v RS=', ' -F'=' '$1=="Foo"' <file> Treat each record to be delimited by ', ', and split each record into fields on the = character (using -F) as well. Then it's just a matter of matching on the first field $1. The suggestion shown here is a simple string matching, feel free to use regexes, ...


3

Another approach: awk 'BEGIN{FS=":|\n";RS=""}NR==1{print $1,$3,$5,$7,$9}{print $2,$4,$6,$8,$10}'


3

Why are you using grep to get stuff out of xml-files? You're using grep, so you're probably on a Linux or BSD system, so why not just use xpath from the command line instead? xpath -q -e "SSID/essid/text()" /path/to/file.xml Will do precisely what you want, and with far less hassle than a regular expression which tend to be rather fragile in getting stuff ...


3

You could do like below, awk -F, '{for(i=1;i<=NF;i++)if($i=="Flag10")print i}' file Example: $ echo ',Flag2,,Flag4,Flag5,,,,,Flag10,Flag11,Flag12,Flag13' | awk -F, '{for(i=1;i<=NF;i++)if($i=="Flag10")print i}' 10


3

To use awk builtin's: awk -F, -v field="Flag10" '{sub(field",.*",field);print split($0,any)}' doc.file The script will remove everything after the first occurrence of the value of field (in this case, Flag10) and then print the result of splitting the line on commas. Since we've deleted everything after Flag10, this results in the number of fields left ...


2

POSIXly you can safely escape any string into one concatenated string for reinput to the shell like: alias "string=$(cat file)"; alias string alias will hard-quote its output and prepend (at least) string= to head of the string. bash (in a break with the standard) also adds the string alias to head of the output. Still, you can get an eval-friendly quoted ...


2

If you only want to escape every double quotation mark and backslash you could use perl -wpe 's/([\\"])/\\$1/g' You could also use this with xclip: cat myfile | perl -wpe 's/([\\"])/\\$1/g' | xclip -selection clipboard


2

Here is a simple Python script to find the count of " in each line of a file: #!/usr/bin/env python2 with open('file.txt') as f: for line in f: print line.count('"') Here we have used the count method of built-in str type.


2

:%s/match\$\zs\(\w\+\)\(.*match\$\)xxx/\1\2\1/ Explanation match\$\zs: anchor the match at the first match$; I use \zs to start the match after that, to avoid yet another capturing group \(\w\+\): capture the text after the first occurrence of match$ \(.*match\$\): capture what's after that, up to the second occurrence of match$, and capture that as we ...


2

Through python3. #!/usr/bin/python3 import csv import sys fil = sys.argv[1] with open(fil) as f: reader = csv.reader(f) for i in reader: l = [] for x in i: if ';' in x: m = x.split(';') l.append(m) else: l.append(x) for j in l[2]: ...


2

You want to print only lines for which the third, fifth, seventh, and ninth fields end with a digit. In that case: $ awk -F, '$3 ~/[[:digit:]]$/ && $5 ~/[[:digit:]]$/ && $7 ~/[[:digit:]]$/ && $9 ~ /[[:digit:]]$/' file RZ_AUTO_507,1hmh,A130,E,A90,A,G80,A,A130,A,AA/GA Naked ribose RZ_AUTO_508,1hmh,A140,E,A90,E,G120,A,A90,A,AA/GA Naked ...


2

You can sort it numerically on the [ delimiter: sort -t\[ -nk2,2 <<\IN int array[0] int array[1001] int array[1002] int array[1003] int array[2] int array[2001] int array[2002] IN OUTPUT int array[0] int array[2] int array[1001] int array[1002] int array[1003] int array[2001] int array[2002]


2

Using sed This will print only lines that start with a positive number: sed -n 's/^\([[:digit:]][^ ,]*\).*/\1/p' Combined with one of your pipelines, it would look like: h5totxt hsli0.126.h5 | harminv -vt 0.1 -w 2-3 -a 0.9 -f 200 | sed -n 's/^\([[:digit:]][^ ,]*\).*/\1/p' How it works -n This tells sed not to print any line unless we explicitly ask ...



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