Ответы:
-FВариант нужен аргумент: -F,например.
Конец awkскрипта должен быть отделен (пробел) с остальными параметрами.
Если разделитель полей установлен ,и вы хотите его сохранить, а номер столбца постоянен и меньше или равен 11, попробуйте следующее:
awk -F, '{print $1,$2,$3,$4,$5,$6,$8,$9,$10,$11,$7}' OFS=, "$file"
command file > newfile && mv newfile file. Тем не менее, новая версия GNU awkдля поддержки этого: gawk -i inplace '{blah blah}' file.
mv newfile fileвы могли использовать cat newfile > file ; rm -f newfile- это сохраняет индекс и права доступа file.
mktempа не жестко кодировать временные имена файлов в сценарии. напримерtf=$(mktemp) ; command file > "$tf" ; cat "$tf" > file ; rm -f "$tf"
Более короткое решение будет
awk -F',+' -v OFS=, '{$(NF+1)=$7; $7=""; $0=$0; $1=$1}1' file
Я не уверен, ,+будет ли работать во всех awkверсиях, но работает, по крайней мере, в GNU awk, также с -cрежимом совместимости.
Объяснение:
$(NF+1)=$7: сначала мы добавляем 7-е поле в конец строки (может быть $12=$7в этом случае)$7="": на следующем шаге 7-е поле стирается (но окружающие разделители остаются)$0=$0), обрабатывая несколько запятых как разделитель полей (это делается через -F',+', здесь +означает один или несколько раз), а также переупорядочить текущую запись через, $1=$1чтобы принудительно перестроить строку, используя ранее установленное поле вывода разделитель (устанавливается опцией -v OFS=,)1Пример ввода:
1,2,3,4,5,6,7,8,9,10,11
выход
1,2,3,4,5,6,8,9,10,11,7
,+должно работать.
all,ball,call,,,fall→ all,ball,call,fall). (2) $(NF+1)=$7это умный подход. ИМХО, $0 = $0 OFS $7немного понятнее, всего пара символов длиннее, и, похоже, делает то же самое. Можете ли вы вспомнить ситуацию, в которой $0 = $0 OFS $7не происходит то же самое, что ваш код?
$0=$0 OFS $7вероятно идентичен $(NF+1)=$7, но только с остальной частью кода без изменений, но не в целом.
Если вы печатаете с OFS=, то есть без разделителя между полями, вы можете просто сохранить значение $7в переменной, установить $7пустое значение и напечатать строку и переменную напрямую. Вам не нужно указывать все поля:
$ cat file
1,2,3,4,5,6,7,8
$ awk -F, -vOFS= '{k=$7; $7=""; print $0,k}' file
12345687
Вы, вероятно, имеете в виду:
awk -F, -v OFS='' '{print $1,$2,$3,$4,$5,$6,$8,$9,$10,$11,$7}' "$file"
awkникогда не видите одинарные кавычки OFS='', верно? Вы также можете просто напечатать OFS=; это точно так же.
Вы специально не сказать , что вы хотите использовать AWK, и вы же говорите , что вы хотите использовать на месте монтажа , как предусмотрено sed -i, так вот sed -iвариант. Обычно awkлучше работать со столбцами, но это один из тех случаев, когда я предпочитаю sed, потому что он, естественно, обрабатывает произвольное количество столбцов.
MOVECOL=7
N=$((MOVECOL-1))
sed -r -e "s/^(([^,]*,){$N})([^,]*),(.*)/\1\4,\3/" -i test.csv
Объяснение:
-r выбирает расширенные регулярные выражения, поэтому мы избегаем большого количества обратной косой чертыКонечно, это не будет работать с файлами, которые скрывают запятые в кавычках (или, что еще хуже, избегают их), но awk не справится и без серьезной акробатики. Если у вас есть эта проблема, вам лучше использовать perlмодуль Text:CSVили pythonмодуль csv.
Пара awkвариантов (при условии, что ваш файл находится внутри переменной $file)
Здесь вы можете выполнить цикл для всех столбцов, распечатать с разделителем полей (OFS) и распечатать терминатор записи (ORS) в конце строки.
awk -F',' -v OFS=, \
'{for(i=1;i<=NF;i++) if (i!=7) printf "%s",$i OFS; \
printf "%s",$7;printf ORS}' "$file"Здесь с использованием регулярных выражений и gensub()функции
gawk -F',+' -v OFS=, '{$0=gensub(/\s*\S+/,"",7) OFS $7}1' "$file"
убить 7- е поле и распечатать его в конце строки.
$0 это целая запись $nэто n- я запись NF количество полей текущей строки OFS выходной полевой разделительORS терминатор выходной записи1это трюк, чтобы сказать awk trueи напечатать default ( $0).Обновить ...
Я почти забыла, что можно сдвинуть все столбцы после 7- го .
awk -F',' -v OFS=, '{tmp=$7; for(i=7;i<=NF;i++) $i=$(i+1); $NF=tmp}1 ' "$file"
OFS $7будет более надежным, чем "," $7. (2) Я считаю, что ", " $7это неправильно, поскольку вопрос указывает, что ОП не хочет пробелов после запятых. (И если бы во входных данных были пробелы после запятых, то $7они уже начинались бы с пробела, и вы бы добавили дополнительный.)
OFS $7, не только более надежное, но и более общее ( «спешка тратит впустую» )
^Указывает на определенную часть команды , где была обнаружена ошибка.