Are there any n-way diff tools with vertical compare? - diff

I started using diffuse, which you can use to compare multiple files together with, but it's some what useless since you can't horizontally compare lines when you have like 20 files you need to compare together, I was thinking maybe one line from all twenty files displayed horizontally.

The editor Vim can do what you are asking. It's a traditionally UNIX program that has been ported to nearly every operating system under the sun, and it's free - yay. In gVim:
Open file A
Choose File -> Split Diff with... and select file B
Choose File -> Split Diff with... and select file C
etc.

Although it's lame, here is what I have reverted to as a quick and dirty solution:
I set a variable called number to the line I want to compare:
set number=10
I wrote the following batch file and installed GNU Utilities:
head -n %number% approval.htm | tail -n 1 >> compare%number%.file
echo approval.htm >> compare%number%.file
head -n %number% checkout.htm | tail -n 1 >> compare%number%.file
echo checkout.htm >> compare%number%.file
head -n %number% confirmation.htm | tail -n 1 >> compare%number%.file
echo confirmation.htm >> compare%number%.file
head -n %number% edit_imprint.htm | tail -n 1 >> compare%number%.file
echo edit_imprint.htm >> compare%number%.file
head -n %number% history.htm | tail -n 1 >> compare%number%.file
echo history.htm >> compare%number%.file
head -n %number% home.htm | tail -n 1 >> compare%number%.file
echo home.htm >> compare%number%.file
head -n %number% imprint.htm | tail -n 1 >> compare%number%.file
echo imprint.htm >> compare%number%.file
head -n %number% mixed.htm | tail -n 1 >> compare%number%.file
echo mixed.htm >> compare%number%.file
head -n %number% office.htm | tail -n 1 >> compare%number%.file
echo office.htm >> compare%number%.file
head -n %number% payment.htm | tail -n 1 >> compare%number%.file
echo payment.htm >> compare%number%.file
head -n %number% report_cat.htm | tail -n 1 >> compare%number%.file
echo report_cat.htm >> compare%number%.file
head -n %number% review.htm | tail -n 1 >> compare%number%.file
echo review.htm >> compare%number%.file
head -n %number% settings.htm | tail -n 1 >> compare%number%.file
echo settings.htm >> compare%number%.file
head -n %number% shopping_cart.htm | tail -n 1 >> compare%number%.file
echo shopping_cart.htm >> compare%number%.file
head -n %number% stock.htm | tail -n 1 >> compare%number%.file
echo stock.htm >> compare%number%.file
head -n %number% warehouse.htm | tail -n 1 >> compare%number%.file
echo warehouse.htm >> compare%number%.file
And the resulting file compare10.file has all of the comparisons in it to be viewed vertically. It's lame but it works.

Related

Split results of du command by new line

I have got a list of the top 20 files/folders that are taking the most amount of room on my hard drive. I would like to separate them into size path/to/file. Below is what I have done so far.
I am using: var=$(du -a -g /folder/ | sort -n -r | head -n 20). It returns the following:
120 /path/to/file
115 /path/to/another/file
110 /file/path/
etc.
I have tried the following code to split it up into single lines.
for i in $(echo $var | sed "s/\n/ /g")
do
echo "$i"
done
The result I would like is as follows:
120 /path/to/file,
115 /path/to/another/file,
110 /file/path/,
etc.
This however is the result I am getting:
120,
/path/to/file,
115,
/path/to/another/file,
110,
/file/path/,
etc.
I think awk will be easier, can be combined with a pipe to the original command:
du -a -g /folder/ | sort -n -r | head -n 20 | awk '{ print $1, $2 "," }'
If you can not create a single pipe, and have to use $var
echo "$var" | awk '{ print $1, $2 "," }'

wc -c gives one more than I expected, why is that?

echo '2003'| wc -c
I thought it would give me 4, but it turned to be 5, what is that additional byte?
Because echo will get a new line.
echo "2014" | wc -c
it will get 5
printf "2014" | wc -c
it will get 4 where printf will not add a new line.
echo contains a built-in switch, -n, to remove newline. So running:
echo -n "2021" | wc -c
Will output the expected 4.
echo adds new line which is causing the issue.
As mentioned by "KyChen", you can use printf or:
a="2014 ;
echo $a |awk '{print length}'

assign actions to one sed address simultaneously for match and non-match

My sed command line script looks like
echo "a,b,c,d" | sed -ne 's/[^a-zA-Z0-9]//g; /^...$/ p; /^...$/! q1'
I want the script to succeed (return-code 0) if there are exactly 3 letters left, and to fail otherwise.
The slightly nagging part is that I have to duplicate the address /^...$/.
I was hoping for something like
echo "a,b,c,d" | sed -ne 's/[^a-zA-Z0-9]//g; /^...$/ p ! q1'
but that doesn't work, at least not with that syntax.
You can use // to represent previously used regex
$ echo "a,b,c,d" | sed -ne 's/[^a-zA-Z0-9]//g; /^...$/ p; //! q1'
$ echo $?
1
$ echo "b,c,d" | sed -ne 's/[^a-zA-Z0-9]//g; /^...$/ p; //! q1'
bcd
$ echo $?
0
Alternatively, you can use b command to start next cycle
$ echo "b,c,d" | sed -ne 's/[^a-zA-Z0-9]//g; /^...$/{p;b}; q1'
bcd
$ echo $?
0
$ echo "a,b,c,d" | sed -ne 's/[^a-zA-Z0-9]//g; /^...$/{p;b}; q1'
$ echo $?
1
This syntax will probably work with GNU sed only. See manual for details

diff between small and larg files not running

i am trying to compare beetwin 2 file and get output if they change
i am missing something
#!/bin/ksh
cd /tmp
FilesDiff=`diif -U 0 /tmp/file1 file2 |grep ^# |wc -l`
countnew = `cat /tmp/file1 |wc -l`
countold = `cat /tmp/file2 |wc -l`
if $FilesDiff != 0 and countnew > countold
then
exit 0
else
exit 1
fi
Yes, you have a spelling error, some parentheses missing around comparisions and some spacing errors. Fix them and the script will work:
#!/bin/ksh
cd /tmp
FilesDiff=`diff -U 0 /tmp/file1 file2 |grep ^# |wc -l`
countnew=`cat /tmp/file1 |wc -l`
countold=`cat /tmp/file2 |wc -l`
if (($FilesDiff != 0)) && (($countnew > $countold))
then
exit 0
else
exit 1
fi

Pattern extraction using SED or AWK

How do I extract 68 from v1+r0.68?
Using awk, returns everything after the last '.'
echo "v1+r0.68" | awk -F. '{print $NF}'
Using sed to get the number after the last dot:
echo 'v1+r0.68' | sed 's/.*[.]\([0-9][0-9]*\)$/\1/'
grep is good at extracting things:
kent$ echo " v1+r0.68"|grep -oE "[0-9]+$"
68
Match the digit string before the end of the line using grep:
$ echo 'v1+r0.68' | grep -Eo '[0-9]+$'
68
Or match any digits after a .
$ echo 'v1+r0.68' | grep -Po '(?<=\.)\d+'
68
Print everything after the . with awk:
echo "v1+r0.68" | awk -F. '{print $NF}'
68
Substitute everything before the . with sed:
echo "v1+r0.68" | sed 's/.*\.//'
68
type man grep
and you will see
...
-o, --only-matching
Show only the part of a matching line that matches PATTERN.
then type echo 'v1+r0.68' | grep -o '68'
if you want it any where special do:
echo 'v1+r0.68' | grep -o '68' > anyWhereSpecial.file_ending