Скопируйте определенные пробелы из файла

Следующие шаги сработали для меня (Ubuntu 14.04 64bit):

  1. wget http://www.apuebook.com/src.3e.tar.gz Скачайте gzipped tar архив с официального сайта книги
  2. tar xzf src.3 e.tar.gz Это создаст разархивированную папку под названием apue.3e в текущем каталоге по умолчанию
  3. cd apue.3e
  4. sudo apt-get install libbsd-dev. Это нужно для ссылки -lbsd в /threads
  5. make Это автоматически скомпилирует весь исходный код во всех папках
  6. cd intro затем ./ls1 ... работает как ожидалось (перечисляет файлы из родительского каталога)

Возможно, вам придется поискать в grep, чтобы найти другие фрагменты кода из книги, но это должно быть просто.

3
23.12.2018, 15:11
5 ответов

Предполагая, что у вас не <TAB>, а несколько пробелов в качестве разделителей полей, и, просмотрев и подсчитав ваши образцы данных, я пришел к

  $ sed -E 's/^(.{15}).{5}/\1/' file
   18DMA      H   0.886   5.687   5.320
   18DMA      H   1.019   5.764   5.247
   18DMA     Np   0.947   5.584   5.151
   18DMA      H   1.033   5.541   5.113
   18DMA     Cn   0.880   5.674   5.050
   18DMA      H   0.831   5.616   4.971
   18DMA      H   0.814   5.751   5.091
   18DMA      H   0.957   5.735   5.003
   18DMA     Cn   0.837   5.486   5.185

Он использует «обратную ссылку» для первых 15 символов, чтобы восстановить их с помощью \1в замещающей части команды замены s.

5
27.01.2020, 21:07
$ awk -v OFS='\t' 'NF == 5 { sub("[0-9]*$", "", $2) } NF == 6 { $0 = $1 OFS $2 OFS $4 OFS $5 OFS $6 } { print }' file
18DMA   H       0.886   5.687   5.320
18DMA   H       1.019   5.764   5.247
18DMA   Np      0.947   5.584   5.151
18DMA   H       1.033   5.541   5.113
18DMA   Cn      0.880   5.674   5.050
18DMA   H       0.831   5.616   4.971
18DMA   H       0.814   5.751   5.091
18DMA   H       0.957   5.735   5.003
18DMA   Cn      0.837   5.486   5.185

Эта короткая awkпрограмма будет выполнять различные действия со строкой ввода в зависимости от того, содержит ли она 5 или 6 полей, разделенных пробелами -.

Если он содержит пять полей, он удаляет все цифры с конца второго поля и оставляет все остальное как есть. Если он содержит шесть полей, он перезаписывает строку, но опускает третье поле.

Вывод будет состоять из табуляции -с разделителями (или с разделителями, установленными для OFSв командной строке ).

4
27.01.2020, 21:07

Используйте cutв символьном режиме:

cut -c1-15,21-

возможно, вам потребуется изменить точные номера символов. Опять же, это предполагает, что ввод не использует символы TAB(\t)в качестве разделителей (, что, вероятно, не так, поскольку тогда у вас не будет проблемы с объединенными полями в первую очередь ).

Если есть табуляции, то программа expandможет преобразовать их в пробелы.

8
27.01.2020, 21:07

На вашем месте я бы сначала "исправил" оригинал, а потом просто удалил столбец. Однако вы можете сделать и то, и другое за один проход :

.
awk '{sub(/[0-9]+/," &",$2); $0=$0; $3=""; print}' input_file

18DMA H  0.886 5.687 5.320
18DMA H  1.019 5.764 5.247
18DMA Np  0.947 5.584 5.151
18DMA H  1.033 5.541 5.113
18DMA Cn  0.880 5.674 5.050
18DMA H  0.831 5.616 4.971
18DMA H  0.814 5.751 5.091
18DMA H  0.957 5.735 5.003
18DMA Cn  0.837 5.486 5.185

Присвоение $0=$0вызовет awkповторное вычисление (и повторное -разделение )текущей строки. В отличие от всех других ответов, это только предположения о возможном формате второго поля, а не о длине или количестве полей.

Версия, которая будет использовать Tab в качестве разделителя выходных полей:

awk -vOFS='\t' '{sub(/[0-9]+/," &",$2); $0=$0; $3=""; sub(OFS OFS,OFS); print}' input_file

18DMA   H       0.886   5.687   5.320
18DMA   H       1.019   5.764   5.247
18DMA   Np      0.947   5.584   5.151
18DMA   H       1.033   5.541   5.113
18DMA   Cn      0.880   5.674   5.050
18DMA   H       0.831   5.616   4.971
18DMA   H       0.814   5.751   5.091
18DMA   H       0.957   5.735   5.003
18DMA   Cn      0.837   5.486   5.185

Дополнительный sub(OFS OFS, OFS)свернет пустое поле, созданное $3="". Это необходимо только в том случае, если файл должен обрабатываться инструментом, который специально ожидает поля с разделителями табуляцией -или по эстетическим соображениям.

0
27.01.2020, 21:07

Как насчет использования vim?

vim +"%s/\([A-Za-z]\)\@<=\s\?\d\+//g" +"w file1" +"q\!" file

это regexв vim commandнаходит точный шаблон, удаляет их и сохраняет файл как файл1 и завершает работу vim. Ваши желаемые отформатированные вещи теперь находятся в file1.
Видите ли, vimв конечном счете принадлежит бедняку ​​sed, awk, perl -e 's/.../', tr, cutи многим другим в целом.

NB:Это также будет работать с vi. Косая черта перед взрывом (\! )ускользает от удара. Регулярное выражение имеет вкус vim -.

1
27.01.2020, 21:07

Теги

Похожие вопросы