wget проблема перенаправления может быть решена при помощи
wget --trust-server-names http://www.example.com/X?1234
Различие находится только в формулировке дополнительного поведения в руководстве V4-V5 - но поведение является тем же повсюду.как есть Результаты реализации V5 идентичны результату System V один, который самостоятельно идентичен GNU tr
поведение с --truncate-set1
опция. Кроме того, "усечение set1 к длине set2" дает тот же результат как "дополняющий string2 с соответствующими символами от string1". Это означает то же самое на практике. Давайте продемонстрируем это.
Во-первых, Вы не должны быть разработчиком, чтобы попытаться скомпилировать это. Сравните исходный код с почти идентичной версией PWB/Unix. Вы будете видеть, что единственная разница зависимостью от "современных" stdio.h активов в основном, таким образом, я лишил источник ее ссылок на inbuf
, fout
, dup
и flush
и замененный оно тем, что PWB/Unix делает - но это никоим образом не должно изменять поведение, поскольку алгоритмы остаются нетронутыми. Я аннотировал тривиальные изменения, которые я внес из оригинала:
#include <stdio.h> <------ added
int dflag = 0; <------ added "=" sign to those
int sflag = 0;
int cflag = 0;
int save = 0;
char code[256];
char squeez[256];
char vect[256];
struct string { int last, max, rep; char *p; } string1, string2;
FILE *input; <------ part of the stdio framework I guess;
main(argc,argv)
char **argv;
{
int i, j;
int c, d;
char *compl;
string1.last = string2.last = 0;
string1.max = string2.max = 0;
string1.rep = string2.rep = 0;
string1.p = string2.p = "";
if(--argc>0) {
argv++;
if(*argv[0]=='-'&&argv[0][1]!=0) {
while(*++argv[0])
switch(*argv[0]) {
case 'c':
cflag++;
continue;
case 'd':
dflag++;
continue;
case 's':
sflag++;
continue;
}
argc--;
argv++;
}
}
if(argc>0) string1.p = argv[0];
if(argc>1) string2.p = argv[1];
for(i=0; i<256; i++)
code[i] = vect[i] = 0;
if(cflag) {
while(c = next(&string1))
vect[c&0377] = 1;
j = 0;
for(i=1; i<256; i++)
if(vect[i]==0) vect[j++] = i;
vect[j] = 0;
compl = vect;
}
for(i=0; i<256; i++)
squeez[i] = 0;
for(;;){
if(cflag) c = *compl++;
else c = next(&string1);
if(c==0) break;
d = next(&string2);
if(d==0) d = c;
code[c&0377] = d;
squeez[d&0377] = 1;
}
while(d = next(&string2))
squeez[d&0377] = 1;
squeez[0] = 1;
for(i=0;i<256;i++) {
if(code[i]==0) code[i] = i;
else if(dflag) code[i] = 0;
}
input = stdin; <------ again stdio
while((c=getc(input)) != EOF ) { <------
if(c == 0) continue;
if(c = code[c&0377]&0377)
if(!sflag || c!=save || !squeez[c&0377])
putchar(save = c);
}
}
next(s)
struct string *s;
{
int a, b, c, n;
int base;
if(--s->rep > 0) return(s->last);
if(s->last < s->max) return(++s->last);
if(*s->p=='[') {
nextc(s);
s->last = a = nextc(s);
s->max = 0;
switch(nextc(s)) {
case '-':
b = nextc(s);
if(b<a || *s->p++!=']')
goto error;
s->max = b;
return(a);
case '*':
base = (*s->p=='0')?8:10;
n = 0;
while((c = *s->p)>='0' && c<'0'+base) {
n = base*n + c - '0';
s->p++;
}
if(*s->p++!=']') goto error;
if(n==0) n = 1000;
s->rep = n;
return(a);
default:
error:
write(1,"Bad string\n",11);
exit(0); <------original was exit();
}
}
return(nextc(s));
}
nextc(s)
struct string *s;
{
int c, i, n;
c = *s->p++;
if(c=='\\') {
i = n = 0;
while(i<3 && (c = *s->p)>='0' && c<='7') {
n = n*8 + c - '0';
i++;
s->p++;
}
if(i>0) c = n;
else c = *s->p++;
}
if(c==0) *--s->p = 0;
return(c&0377);
}
Так cc tr.c
компиляции:
tr.c: In function ‘next’:
tr.c:118:4: warning: incompatible implicit declaration of built-in function ‘exit’
[enabled by default]
exit(0);
^
Но a.out там и работы, поэтому давайте теперь сравним дополнительное поведение этих двух программ, которые мы имеем:
TR GNU
#tr 0123456789 d
0123456789 input
dddddddddd output <----- BSD classic behavior
#tr 0123456789 d123456789 <----- padding set2 with set1 explicitly
0123456789 i
d123456789 o
01234567890123456789 i
d123456789d123456789 o
#tr -t 0123456789 d <----- --truncate-set1 i.e. System V behavior
0123456789 i
d123456789 o <----- concretely, this is what is meant by a result
0012 i where set2 was padded with set1
dd12 o
#tr -t 0123456789 d123456789 <----- padding set2 with set1 explicitly
0123456789 i
d123456789 o <----- note this is identical to the last results
Unix V5 tr + stdio модификация
#./a.out 0123456789 d <----- our compiled version with the classic example
0123456789 i
d123456789 o
./a.out 0123456789 d123456789 <----- padding set2 with set1 explicitly
0123456789 i
d123456789 o
Таким образом, наша версия V5 ведет себя точно как версия System V в этом отношении. Кроме того, явно дополнение set2 с set1 приводит к тому же результату для всех реализаций, потому что это обеспечивает, чтобы set1 и set2 имели то же число элементов (и это - когда у Вас нет этого, которое результаты варьируются исторически).
Наконец, явно дополнение или наличие tr
pad set2 with set1
как описано в оригинале V4-V5 руководства означает то же самое как truncating set1 to the length of set2
поскольку результаты затронуты - это - классическая реализация System V для дополнения и приводит к тем же результатам. V5 tr
не другая реализация, несмотря на различие в страницах справочника.