Tag Info

New answers tagged

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

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


4

You can use FNR to get current line number: awk '{print "\"Process " FNR "\" - " $2}' <in >out


0

You can use this: perl -ane 'if(!$F[1]){print $F[0]," -9\n"}else{print $_;}' This command reads your input line-wise and prints a "-9" in the second column, if it is empty. echo "2342 1 6473 2 7463 2 3647 2734 1 9343" | perl -ane 'if(!$F[1]){print $F[0]," -9\n"}else{print $_;}' 2342 1 6473 2 7463 2 3647 -9 2734 1 9343 -9


1

With GNU sed sed ':;s/^.\{0,9\}$/& /;t;s/^.\{10\}$/&-9/' file Adds one space as long a the number of characters is below ten using test t. Then replaces lines with ten character with themselves and -9.


4

If your data is expressed in fixed width columns, you could do: For the first case: sed 's/^.\{4\}$/& -9/' (add " -9" to lines of 4 characters). For the second case: sed -e '/.\{11\}/b' -e 's/$/ /;s/\(.\{10\}\).*/\1-9/' (add up to 10 spaces and -9 to lines of less than 11 characters). Generally, to parse lines with fixed width fields, ...


0

You can try with this awk with your first example: awk 'NF == 1 { $2 = -9; } 1' file As mentioned in other posts with gawk you can use FIELDWIDTHS, so you can try this with your second one: gawk 'BEGIN { FIELDWIDTHS = "4 1 1 1 2 1 1"} { for (i = 1; i <= NF; i++) { if ($i == "") { if (i == 7) $i = "-9"; else $i = " "; } } printf("%s %s %s %s\n", $1, ...


3

Use join: join -j 1 -a 1 <(sort file1) <(sort file2) -j 1: the join field is the first one -a 1: print unpairable lines from file 1 sort: the files must be sorted for join


2

That's pretty easy with awk: awk 'NR==FNR{a[$1]=$2;next}{print $0,a[$1]}' file2 file1 First (when file2 is being read) we create an array a which stores second column from file2, indexed with first column. And then we print file1 adding value from an array.


1

You can't separate multiple occurrence of whitespaces using cut as per manual: Output fields are separated by a single occurrence of the field delimiter character. unless the text is separated by the same amount or you use tr to remove excess of them. Otherwise use alternative tools such as awk, sed or ex. For example: ex -s +'%norm $2Bd0' +%p +q! ...


0

edit, I misread the question and answered something you weren't asking. Did you want the column entries to be the dictionary keys? So you can check for duplicates when more data arrives? If not, you don't need an associative array, just normal indexed. That will let you start from wherever. Bash doesn't do FP math at all, so having the data in a bash ...


0

with bash: arr1=( $( cut -d' ' -f1 file ) ) arr2=( $( cut -d' ' -f2 file ) ) i.e. cut -field 1 (or 2) using space as -delimiter and assign the output to an array. bash does not distinguish data types in variables, the first index number for any array is 0. Sum with bash and bc echo ${arr2[@]} | sed 's/ /+/g' | bc -l i.e. print all array elements ...



Top 50 recent answers are included