Оставить пробел в строке

У меня есть следующий набор временных данных с двумя наблюдениями. Второе наблюдение содержит пробел в конце. На шаге data _null_ я считываю значение из второго наблюдения с помощью call symput. В операторе put значение записывается в журнал с 6 пробелами: TEXT=Test controltext.

Как я могу добиться, чтобы TEXT=Test controltext печаталось? В наборе временных данных есть некоторые наблюдения с конечным пробелом, а некоторые без него. Так что я не знаю, есть ли конечный пробел...

data temp;
  a="MyTesttext";
  output;
  a="Test ";
  output;
run;

data _null_;
  set temp;
  if _n_ = 2 then do;
    call symput('text',a);
  end;
run;

%put &=text.controltext;

person zuluk    schedule 03.11.2017    source источник
comment
После «Test» в переменной A есть шесть завершающих пробелов, потому что переменная A имеет длину 10. Ваша цель — сохранить один завершающий пробел в значении макропеременной &text?   -  person Quentin    schedule 03.11.2017
comment
Правильно, я хочу сохранить конечный пробел, который записывается в переменную a.   -  person zuluk    schedule 03.11.2017
comment
В другом комментарии вы сказали, что если есть два завершающих пробела, вы хотите их сохранить. В этом случае есть 6 завершающих пробелов, а не один. Но вы хотите сохранить только один? Если бы значение, присвоенное A, было текстом, хотели бы вы сохранить два пробела? Поскольку A=text и A=text имеют по шесть пробелов в конце, вы не можете их различить.   -  person Quentin    schedule 03.11.2017
comment
Я хочу сохранить пробелы, указанные в строке temp. В приведенном выше примере есть один пробел. Если есть 2 или более пробелов, я хочу сохранить эти пробелы.   -  person zuluk    schedule 03.11.2017


Ответы (2)


В языке шага DATA в символьной переменной, если длина значения меньше длины переменной, она дополняется конечными пробелами. Когда вы кодируете a="Test " (один пробел в конце) или a="Test " (три пробела в конце) и переменная A определена с длиной $10, они обе сохраняются с шестью пробелами в конце.

So:

data _null_;
  length a $10;
  a="Test ";
  call symput('TextOneBlank',a);
  a="Test   ";
  call symput('TextThreeBlanks',a);
run;

%put >>&TextOneBlank<<;
%put >>&TextThreeBlanks<<;

возвращает:

75   %put >>&TextOneBlank<<;
>>Test      <<
76
77   %put >>&TextThreeBlanks<<;
>>Test      <<

Один из способов сохранить фиксированное количество завершающих пробелов — добавить собственный разделитель к текстовому значению, чтобы они фактически не заканчивались пробелами. Например, вы можете использовать вертикальную черту в качестве разделителя:

data _null_;
  length a $10;
  a="|Test |";
  call symput('TextOneBlank',scan(a,1,'|'));
  a="|Test   |";
  call symput('TextThreeBlanks',scan(a,1,'|'));
run;

который вернет:

86   %put >>&TextOneBlank<<;
>>Test <<
87   %put >>&TextThreeBlanks<<;
>>Test   <<
person Quentin    schedule 03.11.2017

Результат оператора put содержит «лишние» пробелы, потому что на первом шаге данных вы неявно инициализируете переменную a длиной 10 (длина "MyTesttext").

Как только переменной a длины 10 присваивается значение "Test ", этот дополнительный завершающий пробел практически теряется. Вы можете заметить это, выполнив следующее:

data _null_;
  a="MyTesttext";
  put '"' a +(-1) '"';
  a="Test ";
  put '"' a +(-1) '"';
run;

Результат в логе такой

"MyTesttext"
"Test"

Лишняя заготовка исчезла.

Вы могли бы достичь описанных вами результатов, используя compbl(), но это было бы правильно только в этом конкретном случае, когда у вас был только один пробел в конце.

person user2877959    schedule 03.11.2017
comment
Хм, поэтому я должен указать: если у меня есть 2 конечных пробела, я также хотел бы их сохранить. Это невозможно с compbl(), как вы уже упоминали. - person zuluk; 03.11.2017
comment
При выводе в шаге данных с put другой подход состоит в том, чтобы добавить что-то, а затем удалить это следующим образом, переместив курсор назад на 2 символа: a=cat("Test ", '|'); put '"' a +(-2) '"'; - person Hamish Carpenter; 30.05.2018