2013-03-12 3 views
24

У меня есть файл с тремя столбцами. Я хотел бы удалить третий столбец (редактирование на месте). Как я могу сделать это с помощью awk или sed?удалить столбец с awk или sed

123 abc 22.3 
453 abg 56.7 
1236 hjg 2.3 

Желаемая выход

123 abc 
453 abg 
1236 hjg 
+2

Я озадачен: я открыл щедрость, чтобы продвинуть ответ Эд Мортона, и до сих пор пост с [самыми upvotes] (http://stackoverflow.com/posts/15361632/timeline) в эти дни был вопросом , который не показывал никаких исследований '(@ _ @)'. – fedorqui

ответ

12

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

sed -i -r 's/\S+//3' file 

Если вы хотите удалить пробельные до 3-го поля:

sed -i -r 's/(\s+)?\S+//3' file 
+0

спасибо. – user2160995

+1

@potong, '' S' означает _все символы, которые не являются пробелом_? Где он документирован? –

+1

Что такое '-r'? У моего sed нет этого. –

11

Кажется, вы могли бы просто пойти с

awk '{print $1 " " $2}' file 

Это печатает два первых поля каждой строки в вашем входном файле, разделенные пробелом.

+2

Это предполагает только 3 столбца. В противном случае вам понадобится цикл: 'awk '{printf $ 1 OFS $ 2; for (i = 4; i <= NF; i ++) printf OFS $ i; printf ORS} 'file' (OFS по умолчанию - пробел, а ORS - по умолчанию). –

7

Попробуйте это:

awk '$3="";1' file.txt > new_file && mv new_file file.txt 

или

awk '{$3="";print}' file.txt > new_file && mv new_file file.txt 
44

попробовать эту короткую вещь:

awk '!($3="")' file 
+2

+1 для лучшего ответа awk. –

+23

Это фактически не удаляет данный столбец; он устанавливает его в пустую строку, но вы все равно получаете дополнительную 'FS' в своем выходе. Это может быть или не быть важным, в зависимости от того, что вы делаете с преобразованными данными. – larsks

+0

попробуйте это, чтобы сохранить результат генерации в новый файл. awk '! ($ 3 = "")' file> newfile –

5

GNU AWK 4.1

awk -i inplace NF-- 

Это удалит последнее поле каждой строки.

+0

спасибо !! Очень интуитивно :) –

21

С GNU AWK для Inplace редактирования, \s/\S и gensub() для удаления

1) Первое поле:

awk -i inplace '{sub(/^\S+\s*/,"")}1' file 

или

awk -i inplace '{$0=gensub(/^\S+\s*/,"",1)}1' file 

2) Последнее поле:

awk -i inplace '{sub(/\s*\S+$/,"")}1' file 

или

awk -i inplace '{$0=gensub(/\s*\S+$/,"",1)}1' file 

3) п й поле, где N = 3:

awk -i inplace '{$0=gensub(/\s*\S+/,"",3)}1' file 

Без GNU AWK вам нужен match() + substr() комбо или несколько sub() S + VARS удалить середину поле. См. Также Print all but the first three columns.

+2

Как хорошо иметь такие канонические ответы от вас:) – fedorqui

+2

Примечание: на Ubuntu Trusty GNU Awk 4.0.1 по умолчанию не включено расширение 'awk' inplace. – 2016-07-07 01:41:30

0

Попробуйте использовать разрез ...его быстро и легко

Сначала вы повторяющиеся пробелы, вы можете сжать эти вниз в единое пространство между колоннами, если тот, что вы хотите с tr -s ' '

Если каждый столбец уже имеет только один разделитель между ним, вы можете использовать cut -d ' ' -f-2 печатать поля (столбцы) < = 2.

, например, если ваши данные в файле input.txt вы можете выполнить одно из следующих действий:

cat input.txt | tr -s ' ' | cut -d ' ' -f-2 

Или, если вы лучше Причина об этой проблеме, удалив 3-й столбец можно записать следующее

cat input.txt | tr -s ' ' | cut -d ' ' --complement -f3 

разрез является довольно мощным, вы можете также извлекать диапазоны байтов или символов, в дополнение к столбцам

отрывок из человека странице на синтаксисе, как указать диапазон списка

Each LIST is made up of one range, or many ranges separated by commas. 
Selected input is written in the same order that it is read, and is 
written exactly once. Each range is one of: 

    N  N'th byte, character or field, counted from 1 
    N- from N'th byte, character or field, to end of line 
    N-M from N'th to M'th (included) byte, character or field 
    -M from first to M'th (included) byte, character or field 

так что вы могли бы также сказали, что вы хотите конкретные столбцы 1 и 2 с ...

cat input.txt | tr -s ' ' | cut -d ' ' -f1,2 
Смежные вопросы