Tag Info

New answers tagged

0

Thanks for all the answers. I used a combination answers to achieve my desired result. #!/bin/bash isTable=0 beginTable="^\|\|" lineNum=1 tableCount=0 while IFS= read -r line #Print changes to temp file do if [[ $line =~ $beginTable ]] then if [ "$isTable" -eq "0" ] then isTable=1 ((tableCount++)) ...


1

I'd use perl for this: perl -pe "1 while s/('\w+)_([^']*)/\$1\\u\$2/" <<END my_variable = 'a_string_with_snake_case_inside' delta_llimits=Limits(general_settings['signal_lower_limit'] END my_variable = 'aStringWithSnakeCaseInside' delta_limits=Limits(general_settings['signalLowerLimit'] That means: while the search and replace continues to find ...


4

If I understand correctly, you want to change _x to X as long as it occurs inside '...' strings. Then, with GNU sed, you could do: sed -E ":1;s/^(([^']|'[^']*')*'[^']*)_([^'])/\1\u\3/;t1" That is replace a _X following '... itself following a sequence of either non-quotes or matched quotes. Which on an input like: foo_bar 'ab_cd_ef gh_ij' zz_zz ...


0

You may use python3. with open('/path/file') as f: print('START') for line in f: print(line, end = "") print('END')


4

If you're already using sed, you can use 1 to match the first line and $ to match the last line (see Scott's answer). If you're already using awk, you can use a BEGIN block to run code before the first line and an END block to run code after the last line (see Michael Durrant's answer). If all you need to do is add a header and a footer, just use echo and ...


7

This can be done in sed with sed -e $'1i\\\nSTART' -e $'$a\\\nEND' 1i means insert before line 1; $a means append after the last line.  The $'…' syntax is bash-specific.  In other shells, you should be able to do this with: sed -e '1i\Enter START' -e '$a\Enter END'Enter


10

This works, as indicated by jasonwryan: awk 'BEGIN{print "START"}; {print}; END{print "END"}'


1

Assuming your file names don't contain newline characters and your grep supports the -o option: find [[:upper:]] -type f | grep -Eo '^./[0-9]{3}' | sort | uniq -c


0

This will do what you've asked: for d in */* do n=$(find "$d" -maxdepth 1 -type f -printf "ok\n" | wc -l) printf "%s\t%d\n" "$d" $n done The primary differences to your code are that I've used find instead of ls so that weirdly named files won't break the count (think of \n in a filename), and that I've used printf to format the output.


0

Perhaps something like: find $PWD/ -type f -printf "%h\n\0" | uniq -zc Yield something like: 7 /foo 17 /foo/bar 9 /foo/baz Add a | sort -z before | uniq to sort it.


0

The simplest way to get what you want is to use the -n option to echo when you print the directory name. That avoids printing a newline at the end of whatever you're echoing, so the next output stays on the same line. Other languages may be a better option if you want to collect the information you're looking for and then run multiple transformations on it ...


0

You can built an array of files for each directory separately, and then just count the number of elements. In bash that would be something like for dir in */*/; do a=( "$dir"/* ); printf "%s\t%s\n" "$dir:" "${#a[@]}"; done If A/001 etc. contains directories too which content you would like to include, then add ** glob: shopt -s globstar for dir in */*/; ...


0

Please don't use awk sed etc. They cannot handle XML properly. XML does a bunch of stuff like having whitespace, linefeeds, unary tags etc. that means regular expressions aren't very robust - they break messily, following a perfectly valid change to XML down the line. The way to handle XML is with a parser. xmlstarlet is one commonly used on Linux. Because ...


1

I've found that sort seems to be the fastest uniq tool as shown here --> Fastest way to delete duplicates in large wordlist


3

Content of file: username:email@email.com:password:salt user:name:email@email.com:password:salt username:email@email.com:password:sa:lt user:name:email@email.com:password:sa:lt With GNU sed: sed -E "s/(.*):([^:]*@[^:]*):([^:]*):(.*)/\1', '\2', '\3', '\4/" file Output: username', 'email@email.com', 'password', 'salt user:name', 'email@email.com', ...


0

I'd suggest to write some script/small program that employs XML parser. Then you can count records as they getting parsed and filter out only the stuff you need.


1

The following awk script (plus column for output tabulation) will hande any sequence of placement of the sub-tags, and any whitespace separation of the tags - ie. it will handle the OP's sample input format, as well as the following sample which has no whitespace and differently ordered sub-tags: <HARDWARE><OS>Windows ...


0

with awk - arbitrarily set each column to be 15 characters long, left-aligned and filled with spaces: awk ' BEGIN { FS = "<[A-Za-z/]+>" } { if ( NR % 6 == 0 ) { printf"\n" } else if ( $2 != "" ) { printf"%-15s", $2 } }' file Or as in the other answers in combination with column awk ' BEGIN { FS = "<[A-Za-z/]+>" } { if ( NR % 6 == 0 ) { ...


6

With a slight modification to your XML, wrap all your XML in a parent <DATA> tag1, or another one of your choosing, file called data.xml: <DATA> <HARDWARE> <NAME>WIN1</NAME> <OS>Windows 7</OS> <IP>1.2.3.4</IP> <DOMAIN>contoso.com</DOMAIN> </HARDWARE> <HARDWARE> ...


2

With your example and GNU sed: sed -n 's/<[^>]*>//g;s/^ *//g;/./p' file | paste -d ";" - - - - | column -t -s ";" Output: WIN1 Windows 7 1.2.3.4 contoso.com WIN2 Windows 8 10.20.30.40 contoso.com I assume that your file does not contain a ;. If you need a CSV remove | column -t -s ";".


0

Here's a sed solution using a sliding window (so there are never more than four lines in the pattern space at a time): sed '1{N;N};$!N;/.*\n.*\n.*Fail.*\n.*/{s/^/#/;s/\n/&#/g};P;D' infile On first line it reads in the Next two lines (so now there are three lines in the pattern space). Then, for each input line (including the first one) it pulls in the ...


4

On a GNU system, you can use this: sed -i '/^#[[:blank:]]Person/{n;s/#root:[[:blank:]]\+marc/root:\tsomeone@something.tld/;}' file It searches for a line beginning with # Person. Then switches to the next line and replaces #root:<blanks>marc with root:<tab> .... The -i flag edits the file inplace. -i, \+ and \t are GNU extensions. The ...


0

$ sed -r 'H;1h;$!d;x; s/\n([^\n]*)\n([^\n]*)\n([^\n]*Fail[^\n]*)\n/\n#\1\n#\2\n#\3\n#/g' file Name Number Reason = Pass Reasult Name Number Reason = Pass Reasult #Name #Number #Reason = Fail #Reasult Name Number Reason = Pass Reasult #Name #Number #Reason = Fail #Reasult Name Number Reason = Pass Reasult How it works H;1h;$!d;x These commands read the ...


0

Another gnu sed one-liner: $ sed -rz 's/\n([^\n])/ \1/g;s/\n /\n/g' matrices.txt 1 2 3 4 2 3 4 5 3 4 5 6 3 4 5 6 2 3 2 5 2 3 4 5 2 3 5 6 2 3 4 5 $ Because the -z effectively causes sed to read the whole file as one line, then this will be less suitable for large input files.


1

I would suggest to use perl: perl -p0e 's/(.*\n)(.*\n)(.*Fail\n)/#\1#\2#\3#/g' file Here is how it works: -p: print program in the loop over all input lines -0: assume null as record separator -e: execute program from the command line s/x/y/g: substitute y for x anywhere in the file (): group together regular expressions .*: any character except newline ...


1

sed only: sed '/^$/!{ # if line isn't empty H # append to hold space $!d # if it's not the last line, delete it b end # branch to label end (this happens only if on the last line) } //b end # if line is empty, branch to label end : end # label end x # ...


2

You want to change these "string"s which are in lines where there are no # character or this character is after "string", so that you can have comments at the end of the lines: ##################################### # Blah blah blah string blah blah ##################################### PKG_NAME="string" PKG_DESC="string-foo" PKG_A="string" # this is ...


2

In sed you can stop doing actions if a pattern is found with an exclamation mark: sed '/#/!s/string/replacement/' file I.e. for lines matching '#' (at any position) do not do the replacement - else do. In your case result is: ##################################### # Blah blah blah string blah blah ##################################### ...


2

In Vi/Vim you can run simply: :%j to join all the lines together, or: :%v/^$/-1j to join all matrices separated by new line (Join lines between a certain text pattern in Vim). If you need this done from the command line, try either: ex -s +%j +"wq modified_matrices.txt" matrices.txt to join all lines, or: ex -s +'%v/^$/-1j' +'wq! ...


1

With tr and sed: Replace all newlines with hashes (pick any other symbol that is not present in your matrices if you have hashes), then double hashes are to be newlines and single ones just spaces: (GNUsed) tr '\n' '#' <file | sed 's/##/\n/g;s/#/ /g' POSIX sed tr '\n' '#' <file | sed 's/##/\ /g;s/#/ /g' Regarding the size of the file: ...


4

Possible awk solution could be: awk 'BEGIN { RS = ""; } { $1 = $1; } 1' matrices.txt > modified_matrices.txt


1

You can do that with a little bash script: $ cat data 1 2 3 4 2 3 4 5 3 4 5 6 3 4 5 6 2 3 2 5 2 3 4 5 2 3 5 6 2 3 4 5 $ cat foo.sh #!/bin/bash while read line; do if [[ "${line}" = "" ]]; then echo "" else echo -n "${line} " fi done echo "" $ bash foo.sh < data 1 2 3 4 2 3 4 5 3 4 5 6 3 4 5 6 2 3 2 5 2 3 4 5 2 3 5 6 2 3 4 ...


0

For sed lovers — read file1 for each line in file2 it is not good idea. Much better to use variable: my_var=$(<file1) ; sed "s/$/ $my_var/" file2 or more secure read -r my_var <file1 ; sed "s/$/ $my_var/" file2


4

The reason is probably that / (containing /etc) is a read only filesystem, but has a symlink for /etc/shadow, /etc/passwd, and other dynamic files that lands on a read-write filesystem. This will allow you to edit the shadow and passwd files directly. The sed -i fails because its implementation doesn't actually update in place. Rather, it creates a ...


4

Another awk: $ awk 'BEGIN{getline l <"file1"};{print $0, l}' file2 1 2 3 12 4 5 6 12 7 8 9 12 BEGIN block was executed first before reading input file. The first line in file1 was retrieve using getline() function, stored in variable l With each line of file2, we print it content $0 along with l, separated by OFS, which is a space by default.


0

$ sed -e "s/ *\$/ $(cat file1)/" file2 1 2 3 12 4 5 6 12 7 8 9 12


2

Using awk $ awk -v n=$(cat file1) '{print $0,n}' file2 1 2 3 12 4 5 6 12 7 8 9 12 On csh/tcsh, try: awk -v n=`cat file1` '{print $0,n}' file2 How it works -v n=$(cat file1) This assigns the contents of file1 to the awk variable n. print $0,n This prints each line followed by n. Using sed $ sed '1{h;d}; G;s/\n/ /' file1 file2 1 2 3 12 4 5 6 12 7 ...


0

This should work (in this case file2 gets updated, if you don't want that, remove the -i flag) sed -i "s/.*/& $(cat file1)/" file2


3

Your variable syntax is wrong. A variable is quoted as ${n}. Hence, try sed -i -e "1,${n}d" filename


0

Perl can do it, even across line breaks. Dump this into a file (I'll call it example.html): <p>Here is some <span>foo bar</span> example text.</p> <p>Some text even <span>foo bar</span> spans across line breaks.</p> Then try it out: $ perl -0777 -pe 's/<span.*?span>//gs' example.html <p>Here is ...


0

sed 's/||$/&\n|-/;s/^||/|/;1s/^/{|\n/;$s/-$/}/' file Note \n is GNU sed only, thus should otherwise be sed 's/||$/||\ |-/;s/^||/|/;1s/^/{|\ /;$s/-$/}/' file


0

If you want to replace all numbers that are just 0.xxxx with 0, you could also use sed: sed 's/\(^\| *0\)[\.][^ ]*/\1/g' Where we look for beginning-of-line (^) or one or more spaces (*) followed by a 0 and save that pattern to be printed later followed by a literal . and any number of characters that aren't a space (so, FYI, 0.ignore would get matched) ...


6

sed 's:\\1\\:\ :g' file you will have to escape the backslashes in your match pattern. In the replacement, that's a backslash followed by a literal newline character. Some sed implementations, like GNU sed also support \n there as an non-standard alternative. Output "evSchema" "UAT" "evSN" "uadb" "evDirsep" "/" "evRootPath" "/work_area/APP_UAT/" ...


2

With POSIX awk: awk '!(FNR%3==1)' <file With POSIX sed: sed -e '1d;n;n;d' <file With GNU sed: sed -e '1~3d' <file


0

Here's how to emulate grep -B1 with sed: sed '$!N;/pattern/P;D' infile It's very similar to the one here. Just like the other one, it reads in the Next line but this time, it Prints up to first \newline if the pattern space matches, and then, just like the other one, Deletes up to first \newline and restarts the cycle. So with your sample input: sed ...


2

Substitute is not needed, you can simply delete lines starting by a digit : sed '/^[0-9]/d' And if you really must use substitution : sed 's/^[0-9].*//'


0

Try this: lsb_release -is Per the man page of lsb_release(1): -s, --short Use the short output format for any information displayed. This format omits the leading header(s). On my machine: bburns@bjb-laptop:~$ lsb_release -is Ubuntu


3

Using Awk: awk '{gsub(/^0$/,0.0001)};1' file


19

To replace a single 0 on a line: sed 's/^0$/x/' ^ matches the beginning of the line $ matches the end of a line So the above command matches the beginning of a line, followed by 0, followed by the end of the line.


0

Your regex only matches example.com and sed replaces only example.coms with empty string. Your regex should match any line containing example.com or test.com sed -i 's@.*\(test\|example\)\.com.*@@i' file.txt



Top 50 recent answers are included