Как уменьшить количество разделителей, используя sed или awk
У меня есть данные, которые должны быть 30 столбцов в каждой строке. Экспорт не выполняется идеально, и я иногда получаю 32 - 50 столбцов, потому что в самих полях есть дополнительные разделители табуляции.
Мне также нужно удалить запятые из моих тысяч с помощью следующей программы sed.
sed '/[0-9],[0-9]./ {s/,//g; }' $oldfile > $newfile
Итак, как мне преобразовать следующие данные, исключив запятые и добавив дополнительный разделитель в последний столбец?
вот мой пример ввода:
Column1 Column2 Column3
James 1,203.33 comment1
Mike -3,434.09 testing testing 123
Sarah 1,343,342.23 there here
Я хотел бы вывод:
Column 1 Column2 Column3
James 1203.33 comment1
Mike -3434.09 testing_tab_testing_tab_123
Sarah 1343342.23 there_tab_here
Итак, в конце мне нужно удалить запятые, когда они появляются в числе, я также хочу найти строки с более чем 3 (или соответствующим количеством вкладок), а затем заменить вкладки после трех на вкладку, чтобы я мог иметь дело с ними после того, как я загрузите их в мою базу данных, и все будет в 3 столбцах.
Я надеялся, что смогу сделать это в sed
(на котором я новичок) или awk (я не знаю awk
на всех), потому что sed
действительно быстро обрабатывает все это.
Изменить: это то, что в конечном итоге работает лучше всего в моей ситуации
sed '/[0-9],[0-9]./ {s/,//g; };s/\t/_tab_/3g' input_file
Сначала он удаляет все запятые между двумя числами. Затем он заменяет мои вкладки на "вкладку" после третьего появления. Я проверю это на работе.
Мое рассуждение о том, что я не использую perl, заключается в том, что мои ограниченные знания об этом заставляют меня верить, что для его оценки потребуется загрузить документ в память, а объем этих документов варьируется от 5 до 30 ГБ, что обычно превышает объем памяти моего компьютера.
Я дам вам знать, если что-то пойдет не так, когда я использую это на работе, но я действительно ценю всю помощь.
3 ответа
Сложная часть заменяет эти вкладки. Давайте рассмотрим это поэтапно.
Сначала мы пытаемся заменить каждую вкладку на "_tab_";
sed 's/\t/_tab_/g'
Column1_tab_Column2_tab_Column3
James_tab_1,203.33_tab_comment1
Mike_tab_-3,434.09_tab_testing_tab_testing_tab_123
Sarah_tab_1,343,342.23_tab_there_tab_here
(Обратите внимание, что команда содержит "\t", что означает TAB. Не все версии sed допускают это; вам, возможно, придется использовать реальную вкладку.) После того, как у нас это получится, мы можем попробовать заменить вкладки, начиная с третьей. Некоторые версии sed позволяют это:
sed 's/\t/_tab_/3g'
Если ваш sed не позволяет этого, вам, возможно, придется прибегнуть к замене последней вкладки (если их больше двух):
sed 's/\(\t.*\t.*\)\t/\1_tab_/'
(вы можете или не должны избегать скобок с обратными слешами, как я это сделал) и затем повторять эту операцию, пока она не прекратит делать что-либо, с помощью условного перехода к метке:
sed -e :a -e 's/\(\t.*\t.*\)\t/\1_tab_/;t a'
Если вы так или иначе работаете, удаление запятых относительно просто, вы можете просто добавить еще одно предложение в команду:
... -e 's/\([0-9]\),/\1/g'
Вы можете попробовать это awk
awk -F'\t' -v nbcol=3 '
{a=""
for(i=1;i<=NF;i++)
{if($i~/[-0-9+,\.]*/)
gsub(",","",$i)
if(i>nbcol)a=a"_"$i}
$0=$1 FS $2 FS $3 a
}1' infile.txt
-F '\ t' разделитель полей
nbcol=3 столбца для слияния
Строка a = "" для столбца слияния должна быть инициализирована пустой строкой
for(i=1;i<=NF;i++) работают в каждой строке
если ($ я ~/[-0-9+,.]*/) GSUB (" """, $ я)
Если поле является числом, удалите каждый,
если (я>nbcol) = а "_"$ я}
если номер поля больше, чем nbcol, объединить его в строку
$0=$1 FS $2 FS $3 a
в конце каждой строки регенерируйте $ 0 и выведите строку с 1
Удалить запятые, когда они появляются в числе. Я также хочу найти строки с более чем 3(или соответствующим количеством вкладок), а затем заменить вкладки после трех на вкладку
Чтобы удалить запятые, когда они появляются в числе:
sed -E 's/([0-9]+),/\1/g' inputfile
Чтобы заменить три или более вкладок одной вкладкой:
sed -E 's/\t{3,}/\t/g' inputfile
Или примените обе замены в одной команде:
sed -E 's/([0-9]+),/\1/g;s/\t{3,}/\t/g' inputfile
Пример ввода (здесь \t
означает вкладку):
Column1 Column2 Column3
James 1,203.33 \t\t\t comment1
Mike -3,434.09 \t\t testing testing 123
Sarah 1,343,342.23 \t\t\t there here
Выход:
Column1 Column2 Column3
James 1203.33 \t comment1
Mike -3434.09 \t\t testing testing 123
Sarah 1343342.23 \t there here
Изменить: заменить \t
с _tab_
для 3-го или более вхождений в данной строке вы можете использовать perl:
perl -pe 's{\t}{++$n >= 3 ? "_tab_" : $&}ge' inputfile
Пример ввода:
Column1 Column2 Column3
James \t 1,203.33 \t comment1
Mike \t -3,434.09 \t testing\ttesting\t123
Sarah \t 1,343,342.23 \t there\there
Выход:
Column1 Column2 Column3
James \t 1,203.33 \t comment1
Mike \t -3,434.09 \t testing_tab_testing_tab_123
Sarah \t 1,343,342.23 \t there_tab_here