У меня есть текстовый файл со строками, как показано ниже:

this is the code ;rfc1234;rfc1234
this is the code ;rfc1234;rfc1234;rfc1234;rfc1234

Как я могу сжать повторяющиеся слова в файле до одного слова, как показано ниже:

this is the code ;rfc1234
this is the code ;rfc1234

Я пробовал команду 'tr', но она ограничена только сжатием символов

2
satch_boogie 22 Май 2018 в 18:06

6 ответов

Лучший ответ
sed 's/\(;[^;]*\).*/\1/'  file
0
Ed Morton 22 Май 2018 в 21:37

С sed для произвольных повторяющихся строк с префиксом ;

$ sed -E 's/(;[^;]+)(\1)+/\1/g' file

Или, если вы хотите удалить все после первого токена, не проверяя, соответствуют ли они предыдущему или нет

$ sed -E 's/(\S);.*/\1/' file

Объяснение

(;[^;]+) - захватить строку, начинающуюся с точки с запятой
(\1)+, за которым следует одна и та же захваченная строка один или несколько раз
/\1/g заменить всю цепочку одним экземпляром и повторить

3
karakfa 23 Май 2018 в 15:00

Следующее awk может помочь здесь. Он будет искать все элементы в последнем столбце вашего Input_file и сохранит в нем только уникальные значения.

awk '{num=split($NF,array,";");for(i=1;i<=num;i++){if(!array1[array[i]]++){val=val?val ";" array[i]:array[i]}};NF--;print $0";"val;val="";delete array;delete array1}'   Input_file

Добавляем и не однослойную форму раствора.

awk '
{
  num=split($NF,array,";");
  for(i=1;i<=num;i++){
    if(!array1[array[i]]++){
      val=val?val ";" array[i]:array[i]}
};
  NF--;
  print $0";"val;
  val="";
  delete array;
  delete array1
}'   Input_file

Пояснение :

awk '
{
  num=split($NF,array,";");             ##Creating a variable named num whose value is length of array named array, which is created on last field of line with ; as a delimiter.
  for(i=1;i<=num;i++){                  ##Starting a for loop from i=1 to till value of num each time increment i as 1.
    if(!array1[array[i]]++){            ##Chrcking here a condition if array named array1 index is value of array[i] is NOT coming more than 1 value then do following.
      val=val?val ";" array[i]:array[i]}##Creating a variable named val here whose value is array[i] value and keep concatenating its own value of it.
};
  NF--;                                 ##Reducing the value of NF(number of fields) in current line to remove the last field from it.
  print $0";"val;                       ##Printing the current line(without last field) ; and then value of val here.
  val="";                               ##Nullifying variable val here.
  delete array;                         ##Deleting array named array here.
  delete array1                         ##Deleting array named array1 here.
}'  Input_file                          ##Mentioning Input_file name here.
1
RavinderSingh13 22 Май 2018 в 15:41

Я начал играть с s/(.+)\1/\1/g. Похоже, он работал с Perl (даже нашел is_is_), но не совсем привел меня туда:

$ perl -pe 's/(.+)\1+/\1/g' file
this the code ;rfc1234
this the code ;rfc1234;rfc1234
1
James Brown 22 Май 2018 в 18:06

Вы можете использовать следующую команду для достижения этой цели:

 echo "this is the code ;rfc1234;rfc1234" | sed 's/rfc1234//2g'

 echo "this is the code ;rfc1234;rfc1234;rfc1234;rfc1234" | sed 's/rfc1234//2g'

Или

  sed 's/rfc1234//2g' yourfile.txt
0
Abhijit Pritam Dutta 22 Май 2018 в 15:27

Это может сработать для вас (GNU sed):

sed -r ':a;s/(\S+)\1+/\1/g;ta' file

Регулярное выражение повторяется до тех пор, пока не останется только первый шаблон.

0
potong 23 Май 2018 в 07:38